zsh-users / zsh-syntax-highlighting Goto Github PK
View Code? Open in Web Editor NEWFish shell like syntax highlighting for Zsh.
Home Page: github.com/zsh-users/zsh-syntax-highlighting
License: BSD 3-Clause "New" or "Revised" License
Fish shell like syntax highlighting for Zsh.
Home Page: github.com/zsh-users/zsh-syntax-highlighting
License: BSD 3-Clause "New" or "Revised" License
Scenario:
echo "foo bar"<ENTER>
!!<ENTER>
echo "foo bar"
is not highlighted when redisplayed in the buffer.
Somwhere (I grepping didn't find it) a function called "redo" is defined
» which redo
redo () {
builtin zle .redo && _zsh_highlight-zle-buffer
}
this conflicts with a program I'm using.
prefixing all internal functions would fix this.
Thanks
Alt-q
to queue itEnter
to pop the queued commandIt seems that some aliases which contain some hyphens yeild an error.
% alias l='ls -sF --color=auto'
% l
_zsh_highlight-zle-buffer:local:16: not valid in this context: -sF
Below diff fixes this problem, I believe.
https://gist.github.com/760562
(https://gist.github.com/raw/760562/ceb62e02830c37afdb5b4dd6b7b4d4ac9ebeb1b5/0001-Fix-for-some-aliased-commands.patch)
PS: Pretty nice! I love this fancy eye-candy. Thanks!
This script is extremely slow. Once we are satisfied with the level of highlighting, it will most likely have to be rewritten in C as a ZSH patch and enabled via a shell option such as setopt syntax_highlighting
. Hopefully, it will be accepted.
The modifiers bellow have different implementations; therefore, they have different highlighting. For example, noglob
is implemented as a function while nocorrect
is implemented as a keyword. The implementation details should be abstracted and these modifiers should have a special colour.
PRECOMMAND MODIFIERS
A simple command may be preceded by a precommand modifier, which will
alter how the command is interpreted. These modifiers are shell
builtin commands with the exception of nocorrect which is a reserved
word.
- The command is executed with a `-' prepended to its argv[0]
string.
builtin
The command word is taken to be the name of a builtin command,
rather than a shell function or external command.
command [ -pvV ]
The command word is taken to be the name of an external command,
rather than a shell function or builtin. If the POSIX_BUILTINS
option is set, builtins will also be executed but certain spe-
cial properties of them are suppressed. The -p flag causes a
default path to be searched instead of that in $path. With the
-v flag, command is similar to whence and with -V, it is equiva-
lent to whence -v.
exec [ -cl ] [ -a argv0 ]
The following command together with any arguments is run in
place of the current process, rather than as a sub-process. The
shell does not fork and is replaced. The shell does not invoke
TRAPEXIT, nor does it source zlogout files. The options are
provided for compatibility with other shells.
The -c option clears the environment.
The -l option is equivalent to the - precommand modifier, to
treat the replacement command as a login shell; the command is
executed with a - prepended to its argv[0] string. This flag
has no effect if used together with the -a option.
The -a option is used to specify explicitly the argv[0] string
(the name of the command as seen by the process itself) to be
used by the replacement command and is directly equivalent to
setting a value for the ARGV0 environment variable.
nocorrect
Spelling correction is not done on any of the words. This must
appear before any other precommand modifier, as it is inter-
preted immediately, before any parsing is done. It has no
effect in non-interactive shells.
noglob Filename generation (globbing) is not performed on any of the
words.
xargs
should be added to the ZSH_HIGHLIGHT_TOKENS_FOLLOWED_BY_COMMANDS
echo "foo ( bar"
should not have its parenthesis highlighted.
On line 25, what's the 10th element of ZLE_TOKENS_FOLLOWED_BY_COMMANDS? It shows up for me as a UTF-8 section symbol (two interlocked "S").
Line 30, dirname $arg
would typically be written as ${arg:h} in zsh parlance.
Line 31, print $arg*
throws an error if the NO_MATCH option is set; add "setopt localptions nonomatch", or use
All tests in _check_path could be rewritten with the [[ ... ]] syntax instead of the [ ... ] builtin command.
Line 41, ${BUFFER[$start_pos+1,-1]## #} used to remove leading spaces requires the EXTENDED_GLOB option and will be confused by tabs (which may appear, e.g., in zed, even if the user doesn't type them); "setopt localoptions extendedglob" and use [[:space:]]
Open new terminal
Execute a command, like echo "foo"
Hit CTRL+C
The following message appears once:
Command 'echo' is available in '/bin/echo'
echo: command not found
There must some variable leaking.
I'm trying to tell zsh-syntax-highlighting to trigger more often, but can't figure it out.
Here's what happens. I'll type:
somecommmand --test-me *./face ((((()))))
And there will be no highlighting at all until I hit backspace or enter though.
I'm not sure if something else is conflicting or not. Is there a way to force highlighting with every keypress?
For example, for highlighting in red if a directory is expected but a file was given, etc.
This would avoid having the ZSH_HIGHLIGHT_TOKENS_FOLLOWED_BY_COMMANDS
array.
All we have to do is to get the tag used for the part of the command, using _complete_help
for example. Styles would then be declared per tag, allowing deep customization of the highlighting à la zstyle
.
For example if someone as an alias for sudo
, it should be added to ZLE_TOKENS_FOLLOWED_BY_COMMANDS
too.
The highlighting only takes place after I hit TAB, backspace, or when the command has already completed. But not during regular, interactive typing. Is that normal behavior or might something else in my configuration be in the way?
Extra closed brackets are displayed as error like they should, but not unclosed brackets
I really like this script and have been using it for several months now.
With the new version that is separated into multiple files, sourcing the script multiple times (through sourcing ~/.zshrc after changes) causes problems.
Running a plain zsh ("zsh -fl"), then sourcing the main script twice via
source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
causes the following issues:
_zsh_highlight_widget_accept-line: job table full or recursion limit exceeded
Backtrace from GDB on Mac OS X Lion:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00007fff5f3fffe0
0x000000010001242a in execode ()
(gdb) bt
#0 0x000000010001242a in execode ()
#1 0x0000000100015e20 in execlist ()
#2 0x000000010001623b in execlist ()
#3 0x000000010001590b in execlist ()
#4 0x000000010001237d in execode ()
#5 0x0000000100016a88 in runshfunc ()
#6 0x0000000100016ea8 in doshfunc ()
#7 0x0000000100308ce8 in execzlefunc ()
#8 0x00000001003146b6 in bin_zle ()
#9 0x000000010000d57f in execbuiltin ()
#10 0x0000000100014a1d in execode ()
#11 0x0000000100015e20 in execlist ()
#12 0x000000010001623b in execlist ()
#13 0x000000010001590b in execlist ()
#14 0x000000010001237d in execode ()
#15 0x0000000100016a88 in runshfunc ()
#16 0x0000000100016ea8 in doshfunc ()
#17 0x0000000100308ce8 in execzlefunc ()
#18 0x00000001003146b6 in bin_zle ()
#19 0x000000010000d57f in execbuiltin ()
#20 0x0000000100014a1d in execode ()
#21 0x0000000100015e20 in execlist ()
#22 0x000000010001623b in execlist ()
#23 0x000000010001590b in execlist ()
#24 0x000000010001237d in execode ()
#25 0x0000000100016a88 in runshfunc ()
#26 0x0000000100016ea8 in doshfunc ()
This goes on and on, looking like a recursion and indicating a bug in zsh. Probably it should have shown the same error as the one on Debian.
While this is not a show-stopper, it would be great if it could be fixed.
Thanks.
When I type:
ps aux | grep
Here is what I get:
_check_path:4: no matches found: p*
ps _check_path:4: no matches found: a*
a_check_path:4: no matches found: au*
au_check_path:4: no matches found: aux*
ux _check_path:4: no matches found: aux*
_check_path:4: no matches found: |*
| _check_path:4: no matches found: aux*
_check_path:4: no matches found: |*
_check_path:4: no matches found: g*
g_check_path:4: no matches found: aux*
_check_path:4: no matches found: |*
_check_path:4: no matches found: gr*
gr_check_path:4: no matches found: aux*
_check_path:4: no matches found: |*
_check_path:4: no matches found: gre*
re_check_path:4: no matches found: aux*
_check_path:4: no matches found: |*
grep
Here are my options:
$ setopt
autocd
autocontinue
noautomenu
autonamedirs
autopushd
autoresume
nobareglobqual
nobeep
nocaseglob
cbases
cdablevars
chaselinks
combiningchars
completeinword
correct
correctall
emacs
extendedglob
extendedhistory
globcomplete
globdots
nohashcmds
nohashdirs
nohistbeep
histexpiredupsfirst
histfindnodups
histignoredups
histreduceblanks
histsavenodups
histsubstpattern
histverify
incappendhistory
interactive
nolistbeep
listpacked
login
longlistjobs
monitor
pathdirs
printeightbit
promptsubst
pushdignoredups
pushdtohome
rcexpandparam
rematchpcre
sharehistory
shinstdin
zle
Here is an example of custom key binding I have in my conf.
It does not work anymore since a765f76, because the scripts rebinds it with a leading dot at this line.
I have following code in my .zshrc:
tcsh-backward-delete-word () {
local WORDCHARS="${WORDCHARS:s#/#}"
zle backward-delete-word
}
zle -N tcsh-backward-delete-word
bindkey "^[^?" tcsh-backward-delete-word
Basically it maps tcsh-style backward-delete-word to alt+backspace.
When I source zsh-syntax-highlighting.zsh and hit alt+backspace I get:
No such widget `.tcsh-backward-delete-word'
If someone uses "setopt nounset" for the interactive shell, line 30 in the colorize-zle-buffer function will try to access an unset variable and cause the shell to become unusable. The fix is to either add "setopt localoptions unset" to the start of the function, or change the variable to use ${...:-} to probe if the value is set without causing an error. The latter fix looks like this (note the added ":-" prior to the ":+yes"):
[[ ${${ZLE_TOKENS_FOLLOWED_BY_COMMANDS[(r)${arg//|/\|}]:-}:+yes} = 'yes' ]] && colorize=true
python in which python
is not a command, but an argument to a command. Highlighting it as a command is not only wrong, but confusing. Arguments after whence, which, where, whereis, xargs, zargs, apropos, sudo, builtin, command, and so on, should not be highlighted.
Highlighting python in nocorrect python
is ok since nocorrect is not a command but a shell keyword.
With the newest version:
% cd /etc ~
% 6/etc
The old version was not really better:
% cd /etc ~
% ~arg
My RPROMPT is '%{$c%}%~%{$r%}' where r=$'\e[m' and c=$'\e[0;36m'
Hi Julien,
Thanks for your reply to my question at the Zsh user mailing list. I read your README.md document. Could you tell me how I "just source" the script from my ~/.zshrc ??
I tried to include something like:
zle -N zsh-syntax-highlighting
However, obviously I am missing something.
Best wishes,
Guido van Steen
P.S. Sorry for hardly knowing a thing about "sourcing" nor git.
When I was trying to change the color of search highlighting, it could simply be customized like this:
ZSH_HIGHLIGHT_STYLES[isearch]='fg=cyan,standout'
ZSH_HIGHLIGHT_STYLES[special]='fg=cyan,standout'
It turns out this is not enough because of this function
# ZLE highlight types.
zle_highlight=(
special:$ZSH_HIGHLIGHT_STYLES[special]
isearch:$ZSH_HIGHLIGHT_STYLES[isearch]
)
which uses the default colors, even if a later customization overrides it. Currently I simply copy this function but this is just a hack.
Allow to define a style for redirection tokens. The doc is here.
For example,
% bindkey "^I" complete-word
% bi<TAB>
does not work as expected. This includes list-choices
and maybe some more.
I tackle this problem and make a series of patches which replaces the
clauses after the '# Bind all ZLE events from zle -la to highlighting
function.'.
This is too big for me to descibe its intentions at once in the squashed
patch form, so I split the commits in smaller chunks.
Please take a look some time.
Patch series (3/3) are here.
https://gist.github.com/769487
Thanks for your time.
If you run the following, python
will not be highlighted:
$ which -a python
Where as this would highlight appropriately:
$ which python
I presume that you are a GNU/Linux user. I get the following error on Mac.
readlink: illegal option -- f
usage: readlink [-n] [file ...]
For example:
myvar=myvalue
The script does not check the correspondance between the opening and closing bracket, so it will match (foo]
for example.
It breaks man pages now.
$ man zshall
man:zle: widgets can only be called when ZLE is active
I had to edit one line to fix this bug
((start_pos+=${#BUFFER[$start_pos+1,-1]}-${#${BUFFER[$start_pos+1,-1]## #}}))
became
((start_pos+=${#BUFFER[$start_pos,-1]}-${#${BUFFER[$start_pos+1,-1]## #}}))
.Xdefaults, .zshrc, using rxvt-unicode
Any other relevant info I can attach to see why this happens for me?
You forgot to declare an i variable as local. Trivial fix following.
--- zsh-syntax-highlighting.zsh~ 2011-03-28 15:47:24.000000000 +0200 +++ zsh-syntax-highlighting.zsh 2011-04-04 16:04:23.000000000 +0200 @@ -60,6 +60,7 @@ { local -a funinds local -i rh_size=$#region_highlight + local i for i in {1..${#zsh_highlight_functions}}; do local pred=${zsh_highlight_predicates[i]} cache_place=${zsh_highlight_caches[i]} if _zsh_highlight-zle-buffer-p "$rh_size" "$pred"; then
If the buffer starts with "noglob", *
should not be colorized.
This happens because spacebar is excluded from the self-insert
event and it instead has a separate magic-space
event. Here is the solution for this bug: 0100adc
The following would have proper highlighting on the path:
% cd /Users/clayton/Desktop
But this would not:
% cd ~/Desktop
Same goes for a directory hash, it is not highlighted:
% hash -d L=/var/log
% less ~L/mail.log
In some functions (namely '_zsh_highlight-zle-buffer' and '_zsh_main-highlight') you may want to add 'nowarncreateglobal' to the local setopt's. The reason for this would be to quiet warnings given to the user when the file is sourced with the 'warncreateglobal' option set before-hand. For example; I have 'setopt warncreateglobal' in my ZSH rc at login so when I source this syntax-highlighting file it will verbosely warn about parameters created in those 2 functions everytime I open a terminal.
If you were to tab complete a command, only part of the command ends up being highlighted with the unknown-token
syntax.
Example:
% py<TAB>
% python
|/\ |
| `---`---- No highlighting
`------- The "py" has the "unknown token" highlighting
I apparently failed to noticed that that the expansion "$cmd is") could also fail sometimes with an undefined $cmd (again, with setopt no_unset). I switched
In the new _check_path function, the glob can generate an error (e.g. setopt csh_null_glob or no_match). I added "setopt localoptions null_glob" to the start of the function to avoid this.
Currently:
fg=red,bold
underline
Please color the matches in fg=magenta,standout
just like the fish shell.
I get this error on 4.3.9 on OSX when starting up after sourcing the zsh-syntax-highlight.zsh file in my .zshrc:
/Users/tnaleid/Documents/workspace/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh:128: unrecognized modifier `A'
The offending line of code is:
highlighters_dir="${ZSH_HIGHLIGHT_HIGHLIGHTERS_DIR:-${${(%):-%N}:A:h}/highlighters}"
If I change it to this, it works (pull request forthcoming):
highlighters_dir=`dirname $0`/highlighters
Starting from second line, the first letter of each line is not highlighted.
(anyone confirm ?)
which should be highlighted in all the following cases.
echo (which echo)
echo $(which echo)
I'm not sure if back ticks should be treated like above or like a string.
echo **which** echo
If think these lines :
local aliased_command=${"$(alias $arg)"#*=}
[[ ${${ZSH_HIGHLIGHT_TOKENS_FOLLOWED_BY_COMMANDS[(r)$aliased_command]:-}:+yes} = 'yes' ]] && ZSH_HIGHLIGHT_TOKENS_FOLLOWED_BY_COMMANDS+=($arg)
;;
doesn't check for duplicate in the array and therefore when an alias is evaluated it is added at the end of the array.
For example I have § as an alias for sudo.
After a couple of command starting with § the ZSH_HIGHLIGHT_TOKENS_FOLLOWED_BY_COMMANDS array looks like this :
| || ; & && sudo start time strace noglob command builtin § § § § § § § § § § § § § § § § § § §
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.