Project-wide find and replace in Vim

Find and replace across a project is one of those things that Vim doesn’t do as smoothly as other text editors. And since I do it infrequently, I always forget how to do it. So, I’m putting this in my external memory — this blog post!

These are the steps:

" load all files we want to search into arglist
:args lib/**/*.ex

" find the value in those files
:vimgrep /some_name/g ##

" replace the value in those files
:cdo %s/some_name/some_other_name/ge

" save those files
:cdo update

What does each step do?

  • First, we load all the files in the project into Vim’s arglist with the args command.

  • Then we search for the word we’re trying to replace and load all files that have that word into the quickfix list. We do that with vimgrep, but vimgrep needs to know which file to search in. We want to search in all files in the arglist, so we use ## to get all names in the argument list.

  • Next we perform our substitution in every entry in the quickfix list. We do that with cdo which performs the given action in each entry of the quickfix list.

  • Since we want to substitute some_name with some_other_name, we use our substitution command (s) across the entire file (%), and we do it to all occurrences in the file (g), but we ignore errors (e).

  • Finally, we save all modified files in our quickfix list with cdo and update. Voilà!

Resources

I didn’t come up with this strategy. It’s an updated version of what I found in the always-excellent Vimcasts by Drew Neil: