Zsh tab completions not working as desired for partial paths

autocompletezsh

I want case-insensitive fuzzy completion for files and directories in zsh. After reading the manual for a few hours, this is what I came up with:

zstyle ':completion:*:*:*:*:globbed-files' matcher 'r:|?=** m:{a-z\-}={A-Z\_}'
zstyle ':completion:*:*:*:*:local-directories' matcher 'r:|?=** m:{a-z\-}={A-Z\_}'
zstyle ':completion:*:*:*:*:directories' matcher 'r:|?=** m:{a-z\-}={A-Z\_}'

Additionally, I want pressing TAB once to display possible completions, only modifying what I have typed if there is exactly one completion. Then pressing TAB a second time should put me into "menu completion" mode. Based on the manuals, I came up with this:

zstyle ':completion:*' menu select

Now everything works as it should except in one circumstance. I have two folders Desktop and .rstudio-desktop in my home directory. Since I have setopt globdots, I expect typing the following:

$ cd ~/dktop<TAB>

to leave my command as entered, and display as completion candidates Desktop and .rstudio-desktop. Instead, it removes dktop, leaving me with the following:

$ cd ~/

I have looked at all of the relevant manuals, guides, Stack Exchange questions, and various other sources. But whatever I do, I can't make this work.

Interestingly, though, if I'm in the home directory and type the following then everything works as expected:

$ cd dktop<TAB>

That is, it's only a problem with non-leading segments of paths (and you can see with C-x h that this corresponds to the directories tag rather than the local-directories tag being used).

For easy reproducibility, here is a ~/.zshrc that will reproduce the situation and behavior described above (tested on a fresh El Capitan virtual machine with zsh from Homebrew).

Best Answer

One possible solution is to do:

bindkey "^I" expand-word

This will cause tab to expand ~/ to the absolute path.

Related Question