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
zstyle ':completion:*' matcher-list '' 'l:|=* r:|=*'
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
view but not
vim then pressing Tab after
vi will offer
view but not
_vim, but if you type
vim then completion will offer