23

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).

5
  • Can't reproduce. zsh 5.3.1 on Arch Linux. cd ~/dktop<tab> yields cd ~/Desktop.
    – PythonNut
    Feb 8, 2017 at 21:34
  • @PythonNut With zsh 5.3.1 on OS X the issue does reproduce. It's interesting that there is a difference between the operating systems. Feb 12, 2017 at 21:22
  • 2
    @PythonNut Actually, I bet this is because Linux is case-sensitive and macOS is case-insensitive. Feb 13, 2017 at 22:33
  • 1
    Just as a friendly reminder not all Macs / macOS are case-insensitive it depends on wether your disk is formated case-insensitive or not.
    – konqui
    May 11, 2018 at 15:05
  • 1
    It might've been a bug that has been fixed, because it works correctly for me now with zsh 5.8 on macos. Nov 2, 2021 at 20:36

1 Answer 1

0

One possible solution is to do:

bindkey "^I" expand-word

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

3
  • Maybe I'm missing something, but I don't see how this relates in any way to fuzzy tab completions, or to solving the problem outlined above. If I do as you suggest, then pressing TAB will give me cd /Users/raxod502/dktop, and completion is disabled. May 1, 2018 at 23:01
  • @RadonRosborough The hope was that by expanding ~/ to its absolute path that fuzzy completion would start working. It seemed like one of those cases where the problem is that it evaluates it once but you actually need it to evaluate twice to work, so having the absolute path instead of ~/ would mean it'd go back to only needing one evaluation. But crap, I'm sorry, I forgot that bindkey replaces old bindings, and I can't find anything that says if it's even possible to bindkey two functions to one key. Without my bindkey, does your completion work as intended when given absolute paths? May 2, 2018 at 15:48
  • No. It makes no difference whether the input path is ~/dktop or /Users/raxod502/dktop; the result is the same, namely that dktop is deleted when I press TAB. May 2, 2018 at 21:30

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.