Roben Kleene

Live Search With Vim & Emacs

Think about how search works in your favorite text editor. You probably type your search term then hit enter before your search results start appearing. Now think about how popular apps work: Does Google wait around for enter before showing you results? How about Spotlight? iTunes? Mail? The App Store?

I don’t see any reason programmers’ editors shouldn’t work the same way. The great irony of being a programmer is that you spend all-day improving apps for other people, while your own tools are late to get the same innovations1.

There are a couple of ways to search source code files live today; one day I hope to see this in every text editor.

Emacs

Emacs can do live search using the helm-do-ag command from the helm-ag package2. Here’s what it looks like searching for the string “toggledebugmode” in Web Console’s source code, followed by hitting enter to go to that line of code:

helm-do-ag

fzf

Junegunn Choi’s fantastic command-line filtering utility fzf can also do a live search from the command line, in a manner of sorts. Here’s an example from the fzf wiki3:

# with ag - respects .agignore and .gitignore
ag --nobreak --nonumbers --noheading . | fzf

That’s not useful on it’s own, because all it does is print the selected line to the console. So I wrote a fish shell function that opens the selected line in Vim. Here’s what that looks like, using the same search term as before:

`fzf` Vim Lines

This is piping all the lines of all the files being searched into fzf, which then hides the lines that don’t match your search term. That makes this a filter, not a search, and it means all the lines of all the files being searched need to be stored in memory while the command is running (in other words, it’ll use a lot of RAM). In practice, fzf handles this extremely well4. The helm-do-ag command, on the other hand, performs a real search, which is preferable since only the matchings lines are stored in memory.

So there you have it, a case for improving our current tools and some suggestions for working around those limitations today.


  1. Consider how much find and replace would benefit from a live preview. TextMate 2 and Emacs implement this in some circumstances, but it’s far from typical. ↩︎

  2. Tu Do has a great introduction to the Emacs Helm package; this was the first place I saw live search in Emacs. ↩︎

  3. Both of these commands are powered by The Silver Searcher↩︎

  4. I tried piping a directory of five million lines of code through fzf and it handled it just fine. That’s right, fzf stayed performant filtering five million lines of code live. If that’s not a great illustration of software quality then I don’t know what is. Now it used a lot of RAM, to the tune of 6GB, and I wouldn’t make a habit of doing it regularly, but it’s impressive that it handled it at all. ↩︎