Brendan Dawes
The Art of Form and Code

Crazy-Fast Finding and Opening Files on the Command Line

It's usually always the case that I have a terminal session open somewhere on my Mac — either managing a Git repo, working with a Nodejs instance or a myriad of other reasons. Often times I'm navigating files in the command line, which can be a bit laborious or involve drilling down into directories, remembering structure and the like. Yet there's an easier way involving fuzzy finding using a lovely thing called fzf. It's completely changed how I now find things in the terminal so I wanted to share setting it up and how I use it.

Install fzf

What's fzf? Well from the readme: "It's an interactive Unix filter for command-line that can be used with any list; files, command history, processes, hostnames, bookmarks, git commits, etc." Essentially you can pipe lists into it, filter that list and then use the output however you see fit — opening that file, changing a directory etc etc.

The best way to install it on a Mac is using the package manager Homebrew. Once you have Homebrew installed in the command line type:

brew install fzf

You'll then want to install the special key bindings by running this in the command line:

/usr/local/opt/fzf/install

fzf is now setup and ready to go.

Basic Use

Below shows how fzf works straight out of the box. In this example I want to edit a file in MacVim. I know it's called meshcutup so in the command line I type mvim and then hit CTRL-t to fire up fzf which is now bound to this key mapping. You can see how I can then fuzzy find for this file:

You'll see that at first I type 'pde which looks for files with an exact word match for files with pde, the Processing file extension. Then I start typing meshcutup and fzf fuzzy finds files that match. I can then hit enter when it's found the file I'm after, exiting fzf. I then hit enter again to open than file in MacVim. I didn't have to locate the file before hand by going through directories, I just did a fuzzy find.

Adding a File Preview

We can customise the fzf experience a stage further by adding some options to fzf. To do this add the following lines to your .bash_profile file, which resides in your home directory:

export FZF_DEFAULT_OPTS='--height=70% --preview="cat {}" --preview-window=right:60%:wrap'
export FZF_DEFAULT_COMMAND='rg --files'
export FZF_CTRL_T_COMMAND='$FZF_DEFAULT_COMMAND'

The first line adds some new default options which has the effect of creating a preview window for the file you currently have selected in fzf. The second line tells fzf to use Ripgrep to find files, which I find quicker than the default. To install Ripgrep use homebrew:

brew install ripgrep

The third line binds the CTRL-t command to our new default command. Save those changes then restart your terminal to load these new settings.

Now when we run fzf as before we have a very useful preview window, plus it's even faster...

Open Anything

In the examples so far I've been opening files in Macvim but you can open any file using the open command. For instance I have a pdf on my Mac which is my letter head I use which I print out as needed. This is how quick it is to open that file with fzf:

If I wanted to send that file directly to the printer, without even opening it, I can substitute the open command for lp.

Summary

fzf has completely changed how I work with files in the shell. One of my fave things about it is pressing CTRL-r reveals a command history for the shell which you can then fuzzy search - really useful. If you're a Vim user you can install the fzf vim plugin so you can have the power of fzf inside Vim itself. A word of warning if you use MacVim like me — it renders strangely in MacVim so until there's a fix I don't find it that useful. That said the :Buffers command is great to list and find buffers you have open.

If this floats your boat then you should also check out this great article on using fzf to make a simple note taking app.