Why is zsh (oh-the-zsh) completing directories that don’t exist

autocompleteoh-my-zshosxsubversionzsh

UPDATE 3 I've worked out that these annoying autocomplete options are actually usernames. I.e. they exist in /etc/passwd I have users such as _kadmin_admin and _kadmin_changepw and many others starting with an underscore. This may be specific to OSX.

Oh-my-zsh is autocompleting with these usernames when it can't find any other matches. I tried adding these usernames to the "Don't complete uninteresting users" list in ~/.oh-my-zsh/lib/completion.zsh, but that didn't work. I'm not sure why?

Is there anyway to stop oh-my-zsh from autocompleting usernames?


I'm getting frustrated by some weird behaviour in either ZSH or oh-my-zsh. I'm not sure which would be causing it.

The autocomplete seems to be searching some weird directories that I don't want it to. They appear to be some SVN directories, that I know nothing about and have no idea why they would be in the path. (I don't even use SVN)

This behaviour only seems to occur if there are no other matches in the current directory – it must then look in some other path that I have no idea about.

Example:

NOTE: There is nothing in my home dir that matches mi

→  ~  cd mi<tab>
→  ~  cd _kadmin

I.e. it turns mi into _kadmin. I have no idea why it is matching that directory.

If I try to actually change into that directory, I get an error anyway (as it is not the full directory name):

→  ~  cd _kadmin
cd:cd:10: no such file or directory: _kadmin

If I keep pressing <tab> then it will match the full directory name:

→  ~  cd mi<tab><tab><tab>
→  ~  cd kadmin_admin
→  ~_svn
→  ~_svn pwd
/var/empty

I have no idea what is going on there. I have no idea what kadmin_admin is. And why when I change into it, why would I now get a directory name of ~_svn, and then if I PWD it shows /var/empty

This is my path:

/Users/asgeo1/.rvm/gems/ruby-1.9.3-p194/bin:/Users/asgeo1/.rvm/gems/ruby-1.9.3-p194@global/bin:/Users/asgeo1/.rvm/rubies/ruby-1.9.3-p194/bin:/Users/asgeo1/.rvm/bin:/usr/local/php54/bin:/Users/asgeo1/Projects/dotfiles/bin:/Applications/Postgres.app/Contents/MacOS/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin

Nothing obvious in there that I can see.

Please someone shed some light on this. It's quite frustrating me!

EDIT: Seems someone has had a similar issue before:
Stop tab completion suggesting 'messagebus' There are no answers on there though 🙁

UPDATE: This is the cd function which oh-my-zsh applies:

→  ~  which cd
cd () {
    if [[ "x$*" = "x..." ]]
    then
            cd ../..
    elif [[ "x$*" = "x...." ]]
    then
            cd ../../..
    elif [[ "x$*" = "x....." ]]
    then
        cd ../../..
    elif [[ "x$*" = "x......" ]]
    then
            cd ../../../..
    else
            builtin cd "$@"
    fi
}

Best Answer

_kadmin is probably a completer function for the kadmin tool - not a directory. If you attempt completion on something that zsh can't find as a command, a directory or a valid and known command argument completion, it then starts to offer completion functions as possible expansion candidates. By default, zsh comes with a lot of completers, many of which you may not need - there are bundles for AIX, BSD, Cygwin, various Linux distributions, etc, and they all get read and installed into the shell. If you attempt an expansion on something zsh can't find, it has all those installed completion functions to offer you instead.

You configure zsh not to offer completer functions by putting this in your ~/.zshrc:

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

Reload the file and you should no longer be offered completion functions for tools you don't have installed. Have a look at the zshcompsys manpage for (a lot) more detail.

EDIT in reply to UPDATE 3

If _kadmin is actually a user account, you can configure zsh to not offer it in completions. It seems the approach is to list the user accounts you do want the shell to consider, which limits any names offered only to those listed. The zstyle line is something like this:

zstyle ':completion:*' users asgeo1 root

I think you can list as many users as you like after the users tag. The shell will then only offer those users' home directories as possible completions for the cd function or builtin.

I don't know why adding the username to the ignored-patterns in the completion.zsh file didn't work - did you reload your config after making the change?