On the back of my post about my favourite vim plugins, one tool that sparked particularly more interest was file and keyword searching using fzf & ripgrep. For that, I decided I'd give my 2 pence on what features I use the most and how I have them integrated into my workflow.
Let's start with how you can use it outside of vim
the terminal
fzf
Whether you use bash, zsh or fish, fzf works great with an easy installation process. Just follow along from their github page instructions.
As I'll keep saying, one of the main benefits of using fzf is the speed - it's just incredibly fast. But let's look at the use-cases and see exactly how it can speed up your workflow.
command line search
Whatever code editor you use, you most likely have a file searcher, usually bound to ctrl-t
or ctrl-p
. In vim, a lot of people use ctrlp.vim.
Fzf has this built into the command line, and it's super fast if I didn't already mention.
Simply press ctrl-t
and your files will be loaded, you can use a fuzzy search and look for whatever you need. (fzf will by default ignore what your .gitignore
file contains)
You may ask, what use is this if it just pastes the file to the command line? Well - take it to the next level and pipe (|
) it into a command.
Working on several different features at once in a big application, and forget branch names?
git branch | fzf | xargs git checkout
I personally alias this in my bashrc
as the following, which makes my branch swaps easy as pie: alias gcob='git branch | fzf | xargs git checkout'
command history
This is probably the best feature here. How many times have you typed part of a command and hit ctrl-r
until you reached the right one, only to realise you got part of it wrong and have to history | grep my_command
to figure out what you ran. Not no more.
Fzf has built in ctrl-r
functionality which when you find your command and press return will paste it to your command line, allowing you to edit it before sending it off.
I can't begin to tell you how useful this is.
autocomplete
When searching for a file to edit or a directory to move to you can simply **<tab>
to use fzf and complete your command.
Take it to the next level with ssh support - ssh **<tab>
. Awesome right?
patterns
Fzf also has patterns. Want to find a file that specifically ends in .rb
? Just add $
to the end of the search. Omit specific searches? !ignored_search_result
ripgrep
BurntSushi / ripgrep
ripgrep recursively searches directories for a regex pattern while respecting your gitignore
You've probably guessed by now that I love fast programs. Ripgrep is no exception to the rule. Another tool that outright shows their speed in their readme, it really lives up to it.
You can plug it in to fzf with the following, or use it for simple greps as per below.
export FZF_DEFAULT_COMMAND="rg --files --hidden --follow --glob '!.git'"
On the command line you can use ripgrep as simple as rg 'my_search'
and it will recursively find your results in a flash. And it comes with some great options; --hidden
to show hidden files; -s
for case sensitive searches; -l
to just show the files that contain the result without showing the context; and -g
to include or exclude files or filetypes, such as rg 'my_string' -g '*.rb'
.
But the real fun comes in when you use it in vim.
vim
Both fzf and rg work extremely well with vim. To get started, you'll have to get a couple plugins for fzf.
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
And ripgrep works great with a small command to plug it in.
set grepprg=rg\ --vimgrep\ --smart-case\ --hidden\ --follow
I personally don't use set autochdir
(auto set current directory) so setting the below will use the current working directory (cwd
) for ripgrep.
let g:rg_derive_root='true'
Here are another few configurations I use with fzf & rg in vim. This is personal preference so go ahead and use work makes the most sense to you.
nnoremap \ :Rg<CR>
nnoremap <C-T> :Files<cr>
nnoremap <Leader>b :Buffers<cr>
nnoremap <Leader>s :BLines<cr>
:Files is not working
Check out this github issue if you're having this error. I made the below simple fix in my vimrc and haven't had any problems since.
set rtp+=~/.fzf
set rtp+=/usr/local/opt/fzf
Now the magic happens.
searching
For those of you familiar with vim mappings, you've probably already guessed, but simply press ctrl-t
to open up the menu, and get searching!
As you've probably noticed, this gives you a brilliant preview screen for the file you're planning on opening up. I find this brilliant with no performance change, however if you prefer no preview window, just use :FZF
instead of :Files
.
From inside the menu, fzf will automatically detect ctrl-t
to open the file in a new tab, ctrl-v
for a vertical split or ctrl-x
for a horizontal split.
buffers
I bind <leader>b
for my buffer menu, opening the standard fzf menu for all files in my buffer. This is super useful if you've had a long vim session going.
:BLines
will simply search the current buffer for a specific string. You may be thinking you can do this with vims /
or ?
- but sometimes it's nice to see all occurrences in one window and look through, instead of spamming n
or N
. If you want to look at all the current buffers, you can use :Lines
.
multiple files
One other cool feature from the fzf menu that I mainly use in vim is <tab>
. As you can see below, I've selected several different files and now I can go through them one at a time to see or make the changes I needed.
rg
This plays well with rg
. My \
binding will open a menu and scan all files recursively from your current working directory. Search for the string you want, and use fzf as you would normally.
Bonus - Search & Replace
Whilst we're at it, lets go over a couple ways to find and replace in vim using fzf/rg.
If you search using the above set mapping \
for a keyword you need, and press <tab>
on the files you want to change, vim will then open up a Quickfix list. Inside of here, you can simply :cfdo %s/my_search/replacement/gc
to go over all the changes. You can then :cdo update
or :wqa
to update them all - easy!
If you'd rather do this through the command line, rg
and sed
make this super easy.
rg -l 'my_search' | xargs sed -i 's/my_search/my_new_value/'
and you're done!
If you're using OSX - you may want to note an oddity with sed
addressed here which you can fix by simply changing the command to
rg -l 'my_search' | xargs sed -i '' -e 's/my_search/my_new_value/'
Conclusion
Searching files and their contents is something that any text editor worth using must accommodate. Fzf & Ripgrep makes vim not only accommodate it, but thrive with them. Why settle for anything less?
As always, here are my dotfiles, configuration for vim and other config files. Feel free to check them out!
Cheers :)
Top comments (0)