Question

I changed by shell from bash to zsh and I was wondering if this was possible to fuzzy complete commands just like with the Sublime Text palette. I think that this concept of searching, completing must be everywhere. It's a huge time saving.

Example:

cd dcmts -> cd Documents

cd dwnls/mnf -> cd Downloads/MyNewFolder

I saw the following project and it's not really convincing.

zsh-fuzzy-match

And it's seems to be possible to define some settings or algorithms to configure the behaviour of zsh on completion.

zstyle ':completion:*' completer _complete _match _approximate

zstyle ':completion:*:match:*' original only

zstyle ':completion:*:approximate:*' max-errors 10 numeric

The problem of the two previous solutions is that folders doesn't appears on top of the list when completing while it's often what the user wants.

If you have any interesting .zshrc that statisfy fuzzy search, it would be interesting.

Thanks for your help.

Was it helpful?

Solution 3

Can you give an example of folders doesn't appears on top of the list when completing? It seems you have something in your configuration breaking things for you. Zsh by default will only complete cd with directories:

zsh -f # new Zsh with only default configs
% zstyle ':completion:*' completer _complete _match _approximate
% zstyle ':completion:*:approximate:*' max-errors 3 numeric
% mkdir test && cd test
% mkdir etc && touch et0
% autoload -U compinit && compinit 
% cd et0[TAB] # removes the 'et0' and replaces it with 'etc'.

FWIW, for "searching and completing everywhere" consider trying predict https://stackoverflow.com/a/17230878/766289 (I find it a little insane...)

Also, in Zsh you can do things like:

setopt auto_cd
alias -d build=/home/foo/very/long/path/build # dir alias
build # <-- changes into /home/foo/very/long/path/build

Or just

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' # match upper from lower case
cd d/m[TAB] # just type the initial letter of each dir
cd Downloads/MyNewFolder

I mean cd d/m requires less typing than cd dwnls/mnf ;-)

OTHER TIPS

Try putting this

zstyle ':completion:*' matcher-list 'r:[[:ascii:]]||[[:ascii:]]=** r:|=* m:{a-z\-}={A-Z\_}'

Into your zshrc. It does exactly what you want, and it does it to zsh's own completion system, not to an external completion system.

I suggest you check out fzf, a general purpose fuzzy finder that can process lines from standard input. It's written in Ruby and not a zsh script, so it might not be what you're looking for, but just like zsh-fuzzy-match it sets up CTRL-T binding for your shell and it's pretty straightforward to customize its behavior.

The GIF below shows how it works.

EDIT:

fzf was entirely rewritten in Go and now comes with fuzzy completion support for zsh and bash.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top