zsh-syntax-highlighting/highlighters/main
Daniel Shahaf 8f5d74d219 'main': Further optimize argument parsing.
% repeat 3 { zsh -f tests/test-zprof.zsh main | tee … | grep -w _zsh_highlight | head -n1 }
18)    1       26895.86 26895.86  100.00%      6.35     6.35    0.02%  _zsh_highlight
19)    1       27399.11 27399.11  100.00%      5.52     5.52    0.02%  _zsh_highlight
19)    1       27027.58 27027.58  100.00%      5.66     5.66    0.02%  _zsh_highlight

----

This commit has been rebased.  The above statistics were measured after
the rebase.  The below statistics had been measured before the rebase.

num  calls                time                       self            name
-----------------------------------------------------------------------------------
 1)    3       25689.17  8563.06   98.15%  18422.01  6140.67   70.38%  _zsh_highlight_main_highlighter_highlight_list
 2) 32390        5706.13     0.18   21.80%   2315.68     0.07    8.85%  _zsh_highlight_main_highlighter_highlight_argument
19)    1       26173.33 26173.33  100.00%      5.27     5.27    0.02%  _zsh_highlight

Interestingly, if I make the change in this diff to
_zsh_highlight_main_highlighter_highlight_double_quote —

>     diff --git a/highlighters/main/main-highlighter.zsh b/highlighters/main/main-highlighter.zsh
>     index da6ab2b..bb17618 100644
>     --- a/highlighters/main/main-highlighter.zsh
>     +++ b/highlighters/main/main-highlighter.zsh
>     @@ -1462,10 +1462,13 @@ _zsh_highlight_main_highlighter_highlight_double_quote()
>        local i j k ret style
>        reply=()
>
>     -  for (( i = $1 + 1 ; i <= $#arg ; i += 1 )) ; do
>     +  (( i = $1 ))
>     +  while (( ++i <= $#arg )); do
>     +    i=${arg[(ib.i.)[\"\`\$\\\\${histchars[1]}]]}
>          (( j = i + start_pos - 1 ))
>          (( k = j + 1 ))
>          case "$arg[$i]" in
>     +      ("")  break;;
>            ('"') break;;
>            ('`') saved_reply=($reply)
>                  _zsh_highlight_main_highlighter_highlight_backtick $i

— it actually makes things measurably slower (!), even on input that has
a large number of pasted double-quoted strings: on «BUFFER=": ${(r.8*1500..foo"bar".):-}"»
the slowdown is (1123.24ms / 1091.06ms = 1.0295).  Therefore, I won't be
committing that change.
2020-05-22 04:36:59 +00:00
..
test-data tests: Add a test for the infinite loop fixed by each of the last two commits. 2020-04-03 01:04:31 +00:00
main-highlighter.zsh 'main': Further optimize argument parsing. 2020-05-22 04:36:59 +00:00
README.md docs: Fix broken symlinks 2015-11-24 00:40:09 -06:00

zsh-syntax-highlighting / highlighters / main

This is the main highlighter, that highlights:

  • Commands
  • Options
  • Arguments
  • Paths
  • Strings

This highlighter is active by default.

How to tweak it

This highlighter defines the following styles:

  • unknown-token - unknown tokens / errors
  • reserved-word - shell reserved words (if, for)
  • alias - aliases
  • suffix-alias - suffix aliases (requires zsh 5.1.1 or newer)
  • global-alias - global aliases
  • builtin - shell builtin commands (shift, pwd, zstyle)
  • function - function names
  • command - command names
  • precommand - precommand modifiers (e.g., noglob, builtin)
  • commandseparator - command separation tokens (;, &&)
  • hashed-command - hashed commands
  • autodirectory - a directory name in command position when the AUTO_CD option is set
  • path - existing filenames
  • path_pathseparator - path separators in filenames (/); if unset, path is used (default)
  • path_prefix - prefixes of existing filenames
  • path_prefix_pathseparator - path separators in prefixes of existing filenames (/); if unset, path_prefix is used (default)
  • globbing - globbing expressions (*.txt)
  • history-expansion - history expansion expressions (!foo and ^foo^bar)
  • command-substitution - command substitutions ($(echo foo))
  • command-substitution-unquoted - an unquoted command substitution ($(echo foo))
  • command-substitution-quoted - a quoted command substitution ("$(echo foo)")
  • command-substitution-delimiter - command substitution delimiters ($( and ))
  • command-substitution-delimiter-unquoted - an unquoted command substitution delimiters ($( and ))
  • command-substitution-delimiter-quoted - a quoted command substitution delimiters ("$( and )")
  • process-substitution - process substitutions (<(echo foo))
  • process-substitution-delimiter - process substitution delimiters (<( and ))
  • single-hyphen-option - single-hyphen options (-o)
  • double-hyphen-option - double-hyphen options (--option)
  • back-quoted-argument - backtick command substitution (`foo`)
  • back-quoted-argument-unclosed - unclosed backtick command substitution (`foo)
  • back-quoted-argument-delimiter - backtick command substitution delimiters (`)
  • single-quoted-argument - single-quoted arguments ('foo')
  • single-quoted-argument-unclosed - unclosed single-quoted arguments ('foo)
  • double-quoted-argument - double-quoted arguments ("foo")
  • double-quoted-argument-unclosed - unclosed double-quoted arguments ("foo)
  • dollar-quoted-argument - dollar-quoted arguments ($'foo')
  • dollar-quoted-argument-unclosed - unclosed dollar-quoted arguments ($'foo)
  • rc-quote - two single quotes inside single quotes when the RC_QUOTES option is set ('foo''bar')
  • dollar-double-quoted-argument - parameter expansion inside double quotes ($foo inside "")
  • back-double-quoted-argument - backslash escape sequences inside double-quoted arguments (\" in "foo\"bar")
  • back-dollar-quoted-argument - backslash escape sequences inside dollar-quoted arguments (\x in $'\x48')
  • assign - parameter assignments (x=foo and x=( ))
  • redirection - redirection operators (<, >, etc)
  • comment - comments, when setopt INTERACTIVE_COMMENTS is in effect (echo # foo)
  • comment - elided parameters in command position ($x ls when $x is unset or empty)
  • named-fd - named file descriptor (the fd in echo foo {fd}>&2)
  • numeric-fd - numeric file descriptor (the 2 in echo foo {fd}>&2)
  • arg0 - a command word other than one of those enumerated above (other than a command, precommand, alias, function, or shell builtin command).
  • default - everything else

To override one of those styles, change its entry in ZSH_HIGHLIGHT_STYLES, for example in ~/.zshrc:

# Declare the variable
typeset -A ZSH_HIGHLIGHT_STYLES

# To differentiate aliases from other command types
ZSH_HIGHLIGHT_STYLES[alias]='fg=magenta,bold'

# To have paths colored instead of underlined
ZSH_HIGHLIGHT_STYLES[path]='fg=cyan'

# To disable highlighting of globbing expressions
ZSH_HIGHLIGHT_STYLES[globbing]='none'

The syntax for values is the same as the syntax of "types of highlighting" of the zsh builtin $zle_highlight array, which is documented in the zshzle(1) manual page.

Parameters

To avoid partial path lookups on a path, add the path to the ZSH_HIGHLIGHT_DIRS_BLACKLIST array.

ZSH_HIGHLIGHT_DIRS_BLACKLIST+=(/mnt/slow_share)

Useless trivia

Forward compatibility.

zsh-syntax-highlighting attempts to be forward-compatible with zsh. Specifically, we attempt to facilitate highlighting command word types that had not yet been invented when this version of zsh-syntax-highlighting was released.

A command word is something like a function name, external command name, et cetera. (See Simple Commands & Pipelines in zshmisc(1) for a formal definition.)

If a new kind of command word is ever added to zsh — something conceptually different than "function" and "alias" and "external command" — then command words of that (new) kind will be highlighted by the style arg0_$kind, where $kind is the output of type -w on the new kind of command word. If that style is not defined, then the style arg0 will be used instead.