Fuzzy finding in vim - vim + fzf
13 Nov 2020 | vim neovim pluginFZF is the center-piece of my vim configuration. It is another excellent piece of software by Junegunn Choi.
fzf
is a command line fuzzy finder.
Now, that doesn’t sound like much. But the way it can integrate with your other tools will blow your mind. The repository for FZF is located here and has extensive documentation on how to use it. Follow these instructions to install it.
To see how it works, run this command:
vim $(find . | fzf)
find .
will list all the files in the directory recursively. You pipe that output into fzf
. Fuzzy search for the file of your choice and press enter. fzf
will output that filename and that is passed as an argument to vim
. Pretty neat, huh? fzf
also has a multiselect mode which can be activated with fzf -m
. You can select multiple entries by pressing TAB
.
fzf
has a plugin interface for using it in vim. Before installing and jumping into it, we need to lay some groundwork.
RipGrep
RipGrep is a faster replacement for grep written in rust. Output of some ripgrep commands will be piped into fzf to get our desired setup.
Now, go install ripgrep. The binary is called rg
.
Vim leader key
Vim can map a sequence of keys to an action. Leader is just another key in that sequence. For example,
map <leader>q :q<CR>
will map the sequence <leader>
+ q
to :q <enter>
. The default leader key is \
. You can change the value of leader with :mapleader
. I find space
to be the best key for leader. It is accessible with both fingers and it isn’t really doing anything else in the normal mode. So, go ahead and add this line in your vimrc
.
let mapleader = "\<Space>"
Install fzf.vim
We saw how to install plugins using vim-plug
in another post.
Add these 2 lines to your vimrc(Between plug#begin
and plug#end
).
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Now, let us setup some config and keybindings for useful commands.
" use ripgrep to search for files
let $FZF_DEFAULT_COMMAND = 'rg -l ""'
map <C-p> :Files<CR>
map <C-b> :Buffers<CR>
map <Leader><Leader> :Commands<CR>
map <Leader>/ :execute 'Rg ' . input('Rg/')<CR>
map <Leader>l :BLines<CR>
map <Leader>gf :GF?<CR>
This will create the following mappings
Keybindings | Action |
---|---|
Ctrl + p |
Fuzzy find files in the current working directory |
Ctrl + b |
Fuzzy find open buffers |
space space |
Fuzzy find from a list of all available commands |
space / |
Search for some text within the working directory. Enter the text after pressing space / |
space l |
Fuzzy search lines in the open file |
space g f |
Fuzzy search for files that got added/changed after the last commit |
You can find a list of commands here. See if anything tickles your fancy.
Searching for word under cursor
Something that I do pretty regularly is to search for the word under my cursor. This can be done by defining a vim function. I bind it to space G
(That is an uppercase G).
command! -bang -nargs=* RgExact
\ call fzf#vim#grep(
\ 'rg -F --column --line-number --no-heading --color=always --smart-case -- '.shellescape(<q-args>), 1,
\ fzf#vim#with_preview(), <bang>0)
nmap <Leader>G :execute 'RgExact ' . expand('<cword>') <Cr>