Mar 8, '18

It's dangerous to Vim alone! Take Fzf.

I've been using Vim emulators for a few years, but apparently that wasn't nerdy enough, so I recently made the switch to terminal Vim. Jumping into the world of Vim plugins was daunting, but one specifically has made it a lot easier. Enter fzf.vim by the legendary Junegunn, which is a wrapper for the command line fuzzy finder with the same name, fzf. On the surface it seems like a just another fuzzy finder, but it's much more than that! Let me show you some of my mappings and how I have been using it...

File Finder

The quintessential fuzzy file finder 👌 Here I've mapped <Leader>f to search for git tracked files, and <Leader>F to search all files.

nmap <Leader>f :GFiles<CR>
nmap <Leader>F :Files<CR>

I've never used a faster fuzzy finder, and it seems to sort results more intelligently than most. It's also worth noting that every fzf command displays results in what is called extended search mode, which allows you to narrow results in realtime using an intuitive regex-like syntax.

Buffer Finder

Here I've mapped <Leader>b to search for open buffers, and <Leader>h to search buffer history.

nmap <Leader>b :Buffers<CR>
nmap <Leader>h :History<CR>

These two make it easy to switch between buffers, and order their results by most recent so you can easily switch between your two most recent files without being required to enter a search query.

Tag Finder

Here I've mapped <Leader>t to search for tags in current buffer, and <Leader>T to search for tags across project.

nmap <Leader>t :BTags<CR>
nmap <Leader>T :Tags<CR>

The former doesn't require a tags file, and is a great alternative to packages like tagbar because it's often quicker to fuzzy search for a method name, than it is to navigate your way through a second window. The latter is extremely powerful in combination with a package like gutentags, where searching for indexpostcon will jump you to the index method of your PostController.

Line Finder

Here I've mapped <Leader>l to search for lines in current buffer, <Leader>L to search for lines in loaded buffers, and <Leader>' to search for marked lines.

nmap <Leader>l :BLines<CR>
nmap <Leader>L :Lines<CR>
nmap <Leader>' :Marks<CR>

Honestly, you will get more power out of / and ag, but they require more thought because they aren't fuzzy searches. Being able to fuzzy search through both marked and unmarked lines is fast and forgiving. These can also prove useful when tags aren't available (eg. in .vue components or plain .txt files).

Project Finder

nmap <Leader>a :Ag<Space>

When you need project searching power, most people look to search wrappers like ack.vim. However, these wrappers generally expect you to specify your searchable path before seeing the results.

Fzf's :Ag allows you to focus on your search query first, then narrow down results in realtime using the same extended search mode syntax available to all of fzf's fuzzy finders. Hitting Enter on a single result will open that file, skipping the quickfix window altogether. If you are doing a larger refactor, you can Tab to select multiple results, ALT-A to select all results, then Enter to populate the quickfix window.

It's an incredibly powerful workflow, and my only beef is that it doesn't allow you to pass command line options to ag out-of-the-box ...but it's okay, because I wrote a plugin for that 🚜 If you are interested in learning more about my project searching workflow, I wrote about it here!

Help Finder

nmap <Leader>H :Helptags!<CR>

Sometimes navigating Vim's :help documentation can be painful. Finding the right article can be difficult. Fzf's :Helptags improves this experience, especially when you run it with a bang ! to view results in fullscreen (which by the way, also works on fzf's other commands).

But wait, there's more!

Fuzzy search defined commands, whether they be user defined, plugin defined, or native commands:

nmap <Leader>C :Commands<CR>

Fuzzy search through :command and /search history:

nmap <Leader>: :History:<CR>
nmap <Leader>/ :History/<CR>

Fuzzy search key mappings, which is great for checking against current mappings before defining a new one:

nmap <Leader>M :Maps<CR>

Fuzzy search filetype syntaxes, and hit Enter on a result to set that syntax on the current buffer:

nmap <Leader>s :Filetypes<CR>

So many possibilities, and it's highly extendable if you want to create your own fuzzy finders!

In a deku nutshell...

Fzf's biggest strength is not just it's blazing speed, but also it's consistent interface and extendability for fuzzy finding all the things. It's made me faster at nearly everything I do, and quickly replaced packages like ctrlp, tagbar, ack.vim, etc. If anything, I hope you fuzzy find this enlightening!