Tuesday, February 3, 2015

Vim ranges: an introduction

According to a study conducted in 2015 by the National Association of Search Engine Users’ Board Of Suddenly Saying “Hey, Let’s Check The Google Trends for Vim-Related Searches”, Google gets a fair number of Vim-related queries. The first that has to do with everyday Vim use (coming in fourth most-common, after “vim linux”, “vi vim”, and “windows vim”) is “replace vim”.

On the face of it that might look like the lunatic keyboard smashings of a madperson OK with switching from The Other One True Editor to Notepad or TextEdit or perhaps even Emacs. Google it, however, and the top results are all for replacing text in Vim. They’ll typically show you a variation on this command:

:%s/term/replacement/g

Here, the colon (:) starts a Vim command on the Vim command line. The s is the command (a shortened form of :substitute). term is the search term, replacement is the replacement text, and g is a flag (think “global”) which we’re giving the command. What in the blue blazes is %?!

That, dear fellow Vimmist, is a range.

The range as line numbers


A range is a line number or set of line numbers. Given to a Vim command, it limits the command’s effect to the lines in the range.

We’ll go ahead and use :s as an example, since it’s such a common range-accepting command. Let us say that we mistook ourselves for Johnson (William Cowper’s publisher), hadn’t realized that the year was not 1785, and were taking it upon ourselves to, using Vim, edit this bit from The Garden (Book III of The Task):

1  I see that all are wand'rers, gone astray,
2  Each in his own delusions; they are lost
3  In chace of fancied happiness, still woo'd
4  And never won. Dream after dream ensues;
5  And still they dream that they shall still succeed,
6  And still are disappointed. Rings the world
7  With the vain stir. I sum up half mankind,
8  And add two-thirds of the remaining half,
9  And find the total of their hopes and fears
10 Dreams, empty dreams.

This is basically perfect, so all we can do is make gratuitous modifications which reassure us of our editorial power. For example, we might change “still” to “yet”. To do that on only line 3, where it first shows up, we could run:

:3s/still/yet

But “still” occurs on four lines—from 3 to 6. What if we wanted to get back at the genius for a supposed overuse of the adverb, and replace it on lines 3 to 5?

Well, for one thing, we’d have to put that g flag back on (otherwise, we’d only get the first instance of “still” on line 5, which has two). But most importantly, we’d have to give :s a range with an ending line number. We could do this:

:3,5s/still/yet/g

The range as special characters representing line numbers


Did I say that a range is “a line number or set of line numbers” (hint: I did)? It turns out that that’s not all that can make up a range. There are a number of special characters which we can use to stand for line numbers, too. The full list is at :help :range, but I will steal the top three from there because they’re perhaps the most basically useful:

.    The current line

$    The last line

%    The full file

Aaaaaaaaaaand there we are. I never did explain what % meant, did I? I mean until just now. Just now I did. So there: when you see the :%s in a Vim tutorial somewhere, you know not only the order (yes, I used to always confuse the order of the % and s, because in the early days, all I knew was “this jumble of characters that I just Googled tells Vim to replace text”), but also what the % means (in this context—it’s also a motion).

If we were on line 3 and wanted to change those same occurrences of “still”, we could use the . to say “from this line to line 5”:

 :.,5s/still/yet/g

We could change from line 3 to the end of the file:

:.,$s/still/yet/g 

Although by that point, we might as well decide to, in a fit of rageful fury, destroy the world (in a manner of speaking) and change all occurrences across the entirety of the file:

:%s/still/yet/g

So those are some helpful placeholders for actual line numbers in a range. There’s a deal more to ranges than this; we’re going to get into just one more aspect.

The range as a pattern which depends on the content of the file such that it effectively bypasses the concept of line numbers nearly altogether


This has the potential to be really profoundly effective. Vim allows us to substitute search patterns for line numbers within our range.

Back to our example text. The | is our cursor:

1  I see that all are wand'rers, gone astray,
2  Each in his own delusions; they are lost
3  In chace of fancied happiness, still woo'd
4  And never won. Dream after dream ensues;
5  And still they dream that| they shall still succeed,
6  And still are disappointed. Rings the world
7  With the vain stir. I sum up half mankind,
8  And add two-thirds of the remaining half,
9  And find the total of their hopes and fears
10 Dreams, empty dreams.

Let’s go easy on Cowper, shall we? (He’s the genius, after all. We are only editors.) Let’s only change the first two occurrences of “still” to “yet”.

There are other ways to do this, but here’s how we’d do it using a pattern within a range. We’ll tell :s to only replace instances occurring between “chace” on line 3 and “shall” on line 5:

 :?chace?,/shall/s/still/yet

Now that looks a bit more complex. It’s quite simple though in actuality: ?chace? is a backwards search pattern (remember that in Vim, ? searches backwards), /shall/ is a regular search pattern, and then the command (s) follows with its arguments (still and yet).

For further reading


Juicy details are at :help cmdline-ranges. A user-friendly take, as that help section will tell you, is in the user manual at 10.3 (:help 10.3).

3 comments:

  1. Small typo in the last paragraph, it should read `:help cmdline-ranges` _(i.e. `cmdline` singular instead of plural)_ ... great primer on vim ranges, BTW!

    ReplyDelete
  2. @pvdb, great catch. (And sorry that I didn’t get to this until now!) Double thanks! :-)

    ReplyDelete
  3. CIIT Noida provides Best MCA Courses in Noida based on the current

    IT industry standards that help students to get high paying jobs in Top MNCs. CIIT provides Best MCA Training in Noida, Greater Noida, and Ghaziabad.

    CIIT is one of the trusted MCA training institutes in Noida providing practical knowledge and 100% job assistance with basic as well as advanced

    level MCA subjects. CIITN is the best MCA college in Noida, greater noida, ghaziabad, delhi, gurgaon regoin.

    At CIIT MCA classes in Noida is conducted by subject experts corporate professionals with 9+ years of experience in managing real-time and live

    projects. Sofracle Nano Specialized MCA classes Noida is the perfect blend of academic learning and practical sessions to provide maximum exposure to

    students that transform an average student into a corporate professional whom companies prefer to hire.

    Best MCA College in Noida

    ReplyDelete