Command Line Fuzzy Find with fzf

My first project at Atomic Object indoctrinated me into the magic of VS Code’s fuzzy find feature. It was mind-blowing to jump directly to a file by typing a rough approximation of its full name. Then, my next project found me working in Android Studio and Xcode, both of which implement similarly excellent fuzzy finders.

Bringing Fuzzy Find to the Command Line

But any time I needed to navigate my file system via the command line, I found myself consistently frustrated, having gotten used to quickly jumping around via fuzzy find.

First, I switched from bash to Zsh, getting started quickly with oh-my-zsh for its improved tab-based completions. I still wanted more, though, as opening project directories and manipulating individual files still felt like a chore.

Then I stumbled on an excellent tool called fzf. Fzf brings the convenience and speed of navigating a large file system via fuzzy find into your command line. Out of the box, fzf is good, but not great. Getting it working just right took some extra configuration.

Configuring Fzf

Start by following the installation instructions spelled out in the project’s README page. Then, open up your .zshrc file in your favorite text editor, and add these lines:

# fzf ctrl-r and alt-c behavior
export FZF_BASE="/usr/local/bin/fzf"
export FZF_CTRL_T_COMMAND="fd --hidden --follow --exclude \".git\" . $HOME"
export FZF_ALT_C_COMMAND="fd -t d --hidden --follow --exclude \".git\" . $HOME"

# fzf single quote tab completion behavior
_fzf_compgen_path() {
fd --type f --hidden --follow --exclude .git . "$1"
_fzf_compgen_dir() {
fd --type d . "$1"

Also, be sure to add fzf to your list of oh-my-zsh plugins.

To make this configuration work, follow the installation instructions for fd as well. Fd is a more performant version of the *nix system utility “find.” Fzf uses find in its configuration out of the box, making it almost too slow to use, in my experience.

How it Works

There are two convenient ways to access fzf from the command line: key bindings and autocompletion.

The exported environment variables control the behavior of hitting CTRL + T and ALT + C (or ESC + C on macOS). In this configuration, hitting CTRL + T opens fzf, fuzzy finding through all files within the home directory, and ignoring git ignored files. ALT + C / ESC + C fuzzy finds all directories under the home directory and navigates there immediately.

The two overloaded zsh functions control the behavior of fzf’s tab autocompletion. I didn’t like the default “**” completion token, so I changed it to ” ‘ ” instead. Autocompletion is tied to the current directory instead of the home directory. This allows me to very quickly search within the context of a project using autocomplete, while also navigating my entire file system quickly using the keyboard shortcuts.

I hope this quick overview can help you bring the magic of fuzzy find into your terminal. Check the fzf project Wiki for examples of integrations and customizations you can make to bring fuzzy find to every part of your workflow.