Zsh auto complete suggest complete functions (_git _vim etc)

autocompletezsh

I have a small annoyance with how zsh is doing complete suggestions for my commands.

If I type the beginning of a command that I don't have installed and press tab it will suggest the completion function that is installed.

Lets say I want to execute vim but it isn't installed it will suggest _vim.

Is there a way to turn this off? Or have I done something wrong in my setup?

All my dotfiles are public at github.com/henrikbjorn/castle.

Best Answer

By default, zsh's completion engine only tries to append something to what you type. You configured it to try adding a prefix as well. The simple interactive completion configuration engine (compinstall) offers this under “matching control → substring completion”. This inserts a line like this in your .zshrc:

zstyle ':completion:*' matcher-list '' 'l:|=* r:|=*'

The zstyle builtin sets (mostly) completion settings. The matcher-list completion style is a list of ways to try in succession, stopping when there is at least one match. The empty string means the default completion (suffixes only). The matching control incantation l:|=* r:|=* means to try a prefix matching * and a suffix matching *, i.e. any prefix and suffix.

You can forbid prefixes that begin with _ altogether. This still allows completion of words that begin with _, and completion by adding a prefix, but the prefix may not start with _.

zstyle ':completion:*' matcher-list '' 'l:|=[^_]* r:|=*'

This applies to all completions, not just completions of command names. I don't know how to restrict this to command names.

There should be a way to more precisely exclude command names that begin with _, but I don't know how. A first start is with the ignored-patterns completion style.

zstyle ':completion:*:*:-command-:*:*' ignored-patterns '_*'       

This excludes matches that begin with _; however, if there are no matches, then zsh tries again without the ignore rules. The good of this is that if the command started with an underscore in the first place, it will be completed in this second pass. The bad part is that zsh will thus try adding an underscore anyway if there are no matches, so if you have vi and view but not vim then pressing Tab after vi will offer vi and view but not _vim, but if you type vim then completion will offer _vim.