How I Find and Replace in Vim
Written on September 2, 2015
I'm writing a book about building and deploying web applications with Haskell and Yesod. Want to know when it's released? Click here.
Sandboxing the library is essentially a case of finding all references to the objects and functions the library exports, and attaching them to some named object instead of to the
window, though this is easier said than done.
There are several ways to find and replace in Vim. Most guides I read suggest to use some plugin or some snippet of Vimscript which you should stuff into your
My approach to finding and replacing across the project is with stock Vim, paired with an external grep-like tool — in my case
It seems as though most people reach for plugins by default, and that’s a shame because the tools we have are often powerful enough on their own. Vim is certainly powerful enough by default to perform substitutions across an entire project, with or without confirmation.
Here’s the method I’m using:
:args `ack -l '\bClass\b' --ignore-dir=compiled` :argdo %s/\<Class\>/MooTools.Class/gc | update
The first line populates Vim’s argument list with the result of the external
ack command. I test out my
ack directly in the shell before using it in Vim so I know I’m roughly getting the list of files I want. The
-l flag in
ack tells the tool to just return me the file names. I’m using the
\b word-boundary to refine my search results so I’m not overwhelmed with noise.
The second line uses
argdo to perform some
Ex command across every file in the argument list. In this case, that
Ex command is a buffer-wide substitution, with manual confirmation for each replacement. It’s interesting to note that I’m also using word-boundaries to refine my search results, but Vim’s word-boundaries (
\>) look different from the ones in
The substitute command is passed the
c flags. The
c flag is interesting here; it stands for ‘confirmation’, and will ask me to confirm or deny substitutions with the
The pipe character in the context of an
Ex command is not the same as piping data through the shell; it’s more like a semicolon in C-like languages and allows you to perform separate commands in one move.
I don’t think the commands all together are as interesting as the components they are composed of. Understanding how each of the pieces work in isolation is key to developing proficiency in Vim and in Unix in general.