How to Find and Replace Project-wide in Vim
April 13, 2018The problem
Sometimes one finds themselves with a need to search and replace some text throughout many places in a project. This often happens during a refactor, or when you made a mistake with a CLI code generator (like rails scaffold
), and you accidentally misspell something.
In most modern IDEs, “find and replace all” is pretty simple - highlight the text, Ctrl-Shift-F
, enter the new text, and hit enter. As you know, Vim does things a little differently.
You probably are already aware of how to find and replace all text within a file: : %s/text/newText/g
- “within this file, find all instances of text
, and replace it with newText
.”
But doing so in multiple files at once with just one or two commands has proven difficult until Vim 7.4.8 released the :cdo
and :cfdo
commands. NeoVim with FZF and Ag makes it even easier.
The solution
Setup
- Make sure you’re using Neovim (or Vim 7.4.8+, but really just use Neovim)
- Install FZF for the command line and as a vim plugin
- Install Ag, so that it’s available automatically to FZF in vim
- If using iTerm2 on OSX, set the alt/option key to Esc+
Usage
- Search the text you want to change in the current directory and it’s children with
:Ag text
- Keep typing to fuzzy filter items
- Select items with
alt-a
- Deselect items with
alt-d
Tab
andShift-Tab
will toggle individual items in the list
- Deselect items with
Enter
will populate the quickfix list:cfdo %s/text/newText/g | :w
will substitute all instances oftext
withnewText
that you have selected, and save each file.- Rejoice.
- You can also make a macro to do cool stuff with
:cfdo
rather than just substitution like:cfdo {doCoolStuff} @a
- You can also make a macro to do cool stuff with
Thanks to Github user @trevordmiller for tips on this.