zsh-syntax-highlighting/highlighters/main
Manish Tiwari 3d15f057c1 main: bypass the command-type cache when PATH_DIRS is removed for sudo
Per Copilot review on #987: _zsh_highlight_main__type's cache is keyed
on the command name alone, so classifying a name once under PATH_DIRS
(e.g. as a plain top-level command) would silently poison later
lookups of that same name after sudo -- and vice versa -- regardless
of the PATH_DIRS removal, since the cache lookup happens before
$options_to_set is even consulted.

Give _zsh_highlight_main__type an explicit no_cache parameter, and
add _zsh_highlight_main__type_maybe_no_pathdirs(), a small wrapper
that only shadows $options_to_set (and only bypasses the cache) when
PATH_DIRS was actually present to remove -- so a user without
PATH_DIRS set sees this codepath do nothing at all. Both call sites
in the main word-classification block now go through this wrapper
instead of duplicating the shadowing logic inline.

Strengthened sudo-path_dirs.zsh to classify the same name twice in
one buffer (plain, then sudo-prefixed) specifically to exercise this
cache interaction, not just the PATH_DIRS removal in isolation.

Verified via WSL zsh 5.9: make test passes (same 28 pre-existing
TODO failures, zero new), and the strengthened test fails as expected
(observes "command" instead of "unknown-token" on the sudo-prefixed
occurrence) when run against the pre-fix highlighter.
2026-08-25 09:57:05 +05:30
..
test-data main: bypass the command-type cache when PATH_DIRS is removed for sudo 2026-08-25 09:57:05 +05:30
README.md docs: Fix broken symlinks 2015-11-24 00:40:09 -06:00
main-highlighter.zsh main: bypass the command-type cache when PATH_DIRS is removed for sudo 2026-08-25 09:57:05 +05:30

README.md

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 ))
  • arithmetic-expansion - arithmetic expansion $(( 42 )))
  • 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.