Simple Note-Taking with fzf and Vim

Improve your life with fuzzy finding

Casey Brant
Sep 20, 2017 · 5 min read

TL;DR: (`brew install fzf`), then for a nice little note-taking app.

I recently found , a great utility for general-purpose fuzzy finding on the command line. I’ve been using it — along with Vim and a little bash script — as a fast, simple note-taking tool, and I wanted to share my setup.

Fuzzy Finding

I first learned about fuzzy file finding from . Gary used the for file navigation, and it was kind of mind-blowing to see how fast he was able to switch between files. I was accustomed to laboriously typing out full file paths or clicking through directory trees in my editor, and finding out that I could instead simply type a hotkey and 4 or 5 letters changed how I approached navigating file trees.

Image for post
Image for post
(Fuzzy file finding in action (this is CtrlP, not Command-T, but same idea)

The basic idea of fuzzy finding goes like this: given many possible choices, narrow down the options based on a user-entered string. Unlike traditional text search, the characters in the search string don’t have to appear contiguously in the result to count as a match — only in order. So, by searching for acurc, app/controllers/user_registration_controller.rb is found. The bolded letters are the ones that the fuzzy finder matched on.

fzf

In my daily life, I pretty much only use fuzzy finding for navigating files. That’s not all it can be used for, though, and was built to generalize the idea. fzf is a command-line tool that accepts any input you want to throw at it, presents an interactive fuzzy-finder, then prints whatever you picked on stdout. It has all kinds of options and customizations, and it is blazingly fast. It can handle very large input sets with no trouble at all.

Install fzf

If you’re on a Mac, it’s easy to install fzf:

brew install fzf

It is also available for Windows and Linux, as well as in non-Homebrew form on Mac; check the official docs if you need one of those.

fzf Basic Usage

If you run it without any arguments, fzf will default to recursively finding all files in the current directory.

Image for post
Image for post
fzf default behavior — find files

You can also pipe a list of things into it, for example the results from a big grep search:

grep -r animal . | fzf
Image for post
Image for post
fzf with piped stdin

There are plenty of other possibilities, but those are the two main use cases: run standalone to search filenames, or pipe a list of stuff into it.

A Barebones Note-Taking App

The way I’ve been using fzf is as a lo-fi replacement for (or, more accurately, as a lo-fi replacement for a hi-fi replacement for Notational Velocity, ). I keep a folder of Markdown files in Dropbox as my personal wiki. Everything goes in there, from dates and names I need to remember to cheat sheets for programming languages.

fzf accepts a --preview argument which lets you provide a command to run against the currently selected result line. This lets us do something like this (I’ve also added some preview-window options for cosmetic changes):

fzf --preview="cat {}" --preview-window=right:70%:wrap

and get this result:

Image for post
Image for post
fzf with preview and some presentation options

So that’s a nice little interface over my notes folder. But I want to edit the notes, too, which is where the output from fzf comes in. Since pressing <enter> exits fzf and sends the selected filename to stdout, I can pass that to my editor to open.

vim `fzf --preview="cat {}" --preview-window=right:70%:wrap`
Image for post
Image for post
Give fzf result to Vim

That’s better, but I’m used to notes apps that just stay open all day. I don’t want to retype the fzf command after every edit. After thinking about it for a minute, I realized I could write a bash script that loops forever between these two states — fuzzy file selector and text editor — and here’s what I came up with:

fuz.sh

You can put this script in the root of your notes folder, or do what I did and place it in your PATH so that it’s globally accessible. I also renamed it to just fuz on my machine so it feels more like a normal Unix command.

And the whole thing looks like this:

Image for post
Image for post
fuz.sh in action

But What About…

There’s already an as well as a that does pretty much what I just showed, so why would I bother writing my own wrapper? The main reason is on line 9 of the script: by referencing $EDITOR instead of vim specifically, this supports whatever editor you’d like to use, which I think is a bit more UNIX-y than the plugin approach. Even if you’re a devoted Vim fan, fzf only works in a terminal, so GVim users can’t make use of the existing plugins.

Conclusion

fzf is a really flexible tool, and I’m sure I’ll find other ways to fit it into my workflow in the future, but for now I’m happy with it just as a notes app. If you’re using fzf in some particularly clever way, I’d love to hear from you!

Adorable

Creative technologists solving business problems for people.

Thanks to Jim Remsik and Ryland Herrick

Casey Brant

Written by

People-focused programmer. Software engineer at Adorable (@adorableio)

Adorable

Adorable

Creative technologists solving business problems for people.

Casey Brant

Written by

People-focused programmer. Software engineer at Adorable (@adorableio)

Adorable

Adorable

Creative technologists solving business problems for people.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store