Batch Number Increment in Vim

Desktop Source Code is licensed under Creative Commons Zero

We’re fans of Vim at Collective Idea, with the largest percentage of our staff using it as their primary editor. We’ve even added a few recent [1] converts. Go Vim!

Setting the Stage

This morning I needed to quickly increment multiple sets of numbers. Too tedious to edit each number by hand, I wanted to figure out how to best do this with Vim.

We’ll use a simplified example to demonstrate the task at hand — globally increment a series of numbers by a given value. The first block of HTML is the original code and the second block of HTML is the desired output:

Here are the steps I took and what I found.

A First Pass

I initially reached for Vim’s CTRL-A, a very handy tool for incrementing[2] numbers. Anywhere on the line, 3</code> would increment by 3 the first occurrence of a number relative to the position of the cursor.

Awesome! Except that that only increments the first number and Vim’s single-repeat repeater, instead of moving to the next number, re-increments that number again by 3.

Perhaps one of Vim’s other repeaters, a macro, or single-repeat with an added motion would have worked, but as with most tasks in Vim with excessive repeated keystrokes there’s usually a better way.

Enter Sub-Replace-Expression

Vim’s sub-replace-expression allows the second half of a substitution to contain logic to be evaluated. Prepending a \= signals to Vim that what’s to follow should first be evaluated before being used as the replacement value in the substitution.

In our example, visual line select the second set of

's</code> and execute the command :'<,'>s/\\d\\+/\\=submatch(0)+3/g. Presto! # match against 1 or more digits \d\+ # begin replace expression \= # submatch({nr}) # # return the nth submatch of the matched text, 0 returns # the whole matched text; add 3 submatch(0)+3 # perform the substitution globally /g [1] A convert in progress. I believe in you, Jonathan. [2] CTRL-X handles decrementing.
Photo of Eric Milford

Eric’s career in developing well-architected web applications spans over a decade. He’s worked for established companies and small startups.