Video

Want to see the full-length video right now for free?

Sign In with GitHub for Free Access

Notes

Hello! This is Laila Winner from thoughtbot with another installment of our Vim screencast series. Today I'm going to talk about search and replace using Vim's :substitute command, and the Greplace plugin.

The :substitute command works by searching for a text pattern within a single file and replacing it with a string. The command comprises four parts. This structure is exemplified by the command on the screen:

The first part -- in this example, colon-s -- defines the range in which to perform the search. The second defines the search term. The third -- in this example, Hello -- defines the term to substitute for the search term. The fourth and last part comprises flags which indicate whether you would like Vim to ask for confirmation before performing a substitution, and whether the search ought to be case-insensitive.

Now that we've covered the basic anatomy of the command, let's open up a Markdown file and dig into some of the options :substitute offers.

The search range is highly configurable. Colon-s searches the current line;

:s/prison/cabana/c

colon-percent-s searches the file.

:%s/music/bluegrass/c

It's also possible to specify ranges using line numbers:

:1,41s/music/bluegrass/gci

You can define the search term as a string or a regular expression:

:%s/\w\{5}//c

The c flag indicates that Vim should ask for confirmation before performing a substitution. A lowercase i flag tells Vim to ignore case when searching; an uppercase I makes the search case-sensitive.

Let's try search and replace with :substitute. Let's say I'm on the second line of my file and want to replace the word "world" with "pineapple". I type:

:s/world/pineapple

To replace all the instances of "world" with "pineapple", irrespective of case, I type:

:%s/world/pineapple/gci

I add the 'c' and 'i' flags so I can make sure the substitutions are being performed where I expect.

If I want to replace all occurrences of the word "time" between lines 43 and 67 with "the microwave", I type:

:43,67s/time/the microwave/gi

While the :substitute command is great for search and replace within a single file, sometimes it's nice to be able to search and replace across multiple files in different directories. This is where the Greplace plugin comes in.

A good use case for Greplace is when you want to change the name of a method that is referenced in more than one file. In this example, we're going to rename the poorly-named LocationGeocodingService, defined as a class attribute on the Location class in a Rails application, to simply GeocodingService.

First, use Gsearch to find all instances of location_geocoding_service:

:Gsearch location_geocoding_service app/**/*.rb spec/**/*.rb

Vim opens a buffer with the search results, which we can modify with search and replace using :substitute. To save myself some typing, I use \zs and \ze to set the start and end of the text pattern:

:%s/\zslocation_\zegeocoding_service//gc

Finally, run the :Greplace command to merge the changes:

:Greplace

You will be asked to confirm each of the changes.

That's it for now. If you have any tips or questions about search and replace in Vim, please feel free to take them to our forum at forum.thoughtbot.com.