Does a fuzzy matching mode exist for the zsh shell?

23

12

I've recently fallen in love with efficient text completion systems. One of my favourite kinds of completion is so-called fuzzy completion. This is a mode where the program will complete the user's input based on only a couple of characters that can occur 'anywhere' (almost) in the file name or path. This feature exists at least for these programs:

Usage example of this mode in a text editor:

User is trying to complete the word longWordNameThatTheyDontWantToWriteByHand, and they can do so by typing e.g. the first letter and some of the capital case letters. So typing lwnt could complete to the whole word.

My question is: is there a mode or something similar that I could use with the zsh shell?

sp3ctum

Posted 2012-04-23T12:33:06.403

Reputation: 423

Answers

30

I have this in my .zshrc

# 0 -- vanilla completion (abc => abc)
# 1 -- smart case completion (abc => Abc)
# 2 -- word flex completion (abc => A-big-Car)
# 3 -- full flex completion (abc => ABraCadabra)
zstyle ':completion:*' matcher-list '' \
  'm:{a-z\-}={A-Z\_}' \
  'r:[^[:alpha:]]||[[:alpha:]]=** r:|=* m:{a-z\-}={A-Z\_}' \
  'r:|?=** m:{a-z\-}={A-Z\_}'

It adds full fuzzy matching to zsh's completion engine. It lacks the super smarts of sublime text, but, yes, it will complete lwnt -> longWordNameThatTheyDontWantToWriteByHand.

PythonNut

Posted 2012-04-23T12:33:06.403

Reputation: 674

1I just found a bug: doesn't work for filenames with spaces, given you're typing anything after the space ☹ I.e. stack install && vlc ~/Music/erf doesn't complete to stack install && vlc ~/Music/FGFC820\ -\ Perfect\ War.mp3. – Hi-Angel – 2016-08-28T19:44:43.433

5@Hi-Angel hey, thanks for bumping this. I actually use 'r:|?=** m:{a-z\-}={A-Z\_}' now, which is a bunch simpler, and doesn't suffer from the problem you describe. – PythonNut – 2016-09-01T23:05:12.593

That's great! Maybe you could make a plugin with this code. Just so that it's easier to find. – Julien__ – 2018-11-26T01:13:23.410

16

Check out my project fzf.

It's a general purpose fuzzy finder written in Golang that can be used with any list of things: files, processes, command history, git branches, etc.

For zsh, it provide the following key bindings:

  • CTRL-T - Paste the selected file path(s) into the command line
  • CTRL-R - Paste the selected command from history into the command line
  • ALT-C - cd into the selected directory

and fuzzy completion mode:

# Files under current directory
# - You can select multiple items with TAB key
vim **<TAB>

# Files under parent directory
vim ../**<TAB>

# Files under parent directory that match `fzf`
vim ../fzf**<TAB>

# Files under your home directory
vim ~/**<TAB>

# Directories under current directory (single-selection)
cd **<TAB>

# Directories under ~/github that match `fzf`
cd ~/github/fzf**<TAB>

# Process IDs. Can select multiple processes with TAB or Shift-TAB
kill -9 <TAB>

# Host names
ssh **<TAB>
telnet **<TAB>

# Environment variables / aliases
unset **<TAB>
export **<TAB>
unalias **<TAB>

Junegunn Choi

Posted 2012-04-23T12:33:06.403

Reputation: 406

4How can I make it tab complete with this by default? Without having to type ** – theonlygusti – 2017-11-09T08:00:10.960