Does a fuzzy matching mode exist for the zsh shell?

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:

  • TextMate
  • Vim Command-T plugin https://github.com/wincent/Command-T
  • Vim completion system https://github.com/Shougo/neocomplcache
  • Various modern IDEs

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?


Solution 1:

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.

Solution 2:

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>