During some refactoring, I was hit with the need to do some serious bad-man search and replace across entire directories from within vim, because almost any alternative would be more painful than listening to Cher’s discography and watching The View simultaneously. After scouring Google results for a while, the only article I could find detailing this technique was a pretty good one by Ibrahim Ahmed.
I’ll summarize with an example. Let’s say you have a massive Python project, and
you want to replace every call to certain accessor functions with a variable
name. For example,
say that your Python project is in the
From within vim, we first have to specify which files we want to operate on.
That is, we specify
args as any Python file within any subdirectory of
~/Code/albums. You can use regular expressions here and, in fact, a few
comments on Ibrahim’s site allude to piping in file names with a bash script.
After we have specified the files we want to act on, we specify the action.
Let’s say we have two functions we want to replace:
getToroAlbum. We want to change them to
:argdo %s/get\(TreasureFingers\|Toro\)Album()/\l\1Album/gec | update
Now you’re whipping through each matching instance, yaying or naying each replacement like a glutton prince.
Wait, what? Let’s break down what’s going on here.
:argdo, unsurprisingly, specifies that we’re acting on the args we specified earlier.
%s/foo/bar/gcreplaces each instance of
barand prompts you before doing so.
getToroAlbum()and the escaped parenthesis “capture” either
Torofor later use in the replacement.
\l\1Albumis the meat. The prefix,
\l, tells vim to make the first character of the following back-reference lowercase. The next component,
\1, is a back-reference to the capture (either
Toro), and “Album” is simply appended to the replacement.
gecis used instead of
gcbecause the inclusion of
eavoids error messages in the case that we search a file and don’t find a match (this will happen).
| updatesimply saves the file after we’ve completed the first operation: the find and replace.
More information about case changes within regular expressions can be found here.