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.

  • I've seen this behaviour before, but in my current setup it doesn't seem to be present. Sadly, I have no clue, which of my settings changed that behaviour. – Customizer Feb 20 '14 at 23:25

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.

| improve this answer | |
  • Thanks seems to work by doing one of the solutions you specified, also i learned a bunch about the way it works. – Henrik Bjørnskov Feb 21 '14 at 7:29
  • 2
    The solution with ignore-patterns works just fine for me, even if there are no matches. Just had to make sure that completer does not contain _ignored. – Adaephon May 12 '14 at 12:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.