I do not want filename tab completion to prioritize the start of the file name. For example, given the filenames red_blue.txt and blue_red.txt, I do not want vim red tab to prioritize red_blue.txt
This can be accomplished by using:
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
However, this behaviour will also apply to the tab completion of command names, which I do not want. For example, typing nit tab looking for the command "nitrogen" will also match commands like mkinitcpio, xinit, compinit, and various others.
For commands, I would like the completion to use:
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
How can I have zsh tab completion treat command names and filenames differently?
Best Answer
Generally speaking, you need to refine the
zstyle
call so that it doesn't apply to all completions, but only to file completion. For an ordinary completion, the syntax of the context specifier is:completion:WIDGET:COMPLETER:COMMAND:ARGUMENT:TAG
.WIDGET
is only set by some special widgets, leave it generic (*
).COMPLETER
iscomplete
for normal completion, and can have other values for tasks such as autocorrection.COMMAND
is typically the name of the command whose arguments are being completed. More precisely, it's the word aftercompdef
. Some complex commands change it while completing subcommands. For special places in the shell syntax, it's a context name between dashes, such as-parameter
after a$
or-command-
for the first word in a command.ARGUMENT
is typically something likeargument-3
for the third non-option argument oroption--foo-1
for the argument to the option--foo
.TAG
is used internally by some completion function, often but not always one of the conventional tag names.In
zstyle
declarations, more specific declarations take precedence over less specific ones.:
) is more specific than one with fewer colons.*
is more specific than anything else.Thus, in general, to make an exception for command names, just add another
zstyle
declaration that's specifically about commands.However, there's a twist:
matcher-list
is applied globally, not in the context of completion. In your case, as long as you only want a single matcher, you can usematcher
instead.