OHMS BLOG

Thursday, February 26, 2009

code

A vim lesson

Back when I was a co-op student, one of the developers that trained me had a philosophy that a vi user should learn a new editing trick every day. While I haven't bothered to maintain such a regimen, I do from time to time like to learn new commands as editing situations arise. My latest lesson involved the use of pattern matching to select specific lines within a range, deleting them to a register, and putting them in a different location. Allow me to illustrate with an example.

Suppose I have code like this (familiarity with C-like languages is assumed):

1: char array[3][2];
2:
3: array[0][0] = 'x';

4: array[0][1] = 'y';
5: array[1][0] = 'z';
6: array[1][1] = 'z';
7: array[2][0] = 'y';
8: array[2][1] = '\n';

Let's suppose that I decided that I wanted to group these assignments according to the second index. I want to remove all rows that contain [1] as the second dimension's index and move them elsewhere. How can I do that in vim without deleting each row individually?

:3,8g/.*\[1\] /d A

Let's decompose this. The characters in blue specify the range of lines to consider. I only want vim to look at lines 3 through 8. The g tells vim to apply the pattern match to every line in the range. The yellow text is the pattern match itself. Finally, the delete command is highlighted in orange. This command is repeated for each line that matches the pattern. The uppercase A tells vim to append the line that is deleted into register "a". After this command is run, we'd see:

1: char array[3][2];
2:
3: array[0][0] = 'x';

4: array[1][0] = 'z';
5: array[2][0] = 'y';

Later on, when we want to paste these saved rows, we can position the cursor at line 5 and type the following command:

"ap

This tells vim to put the text in register "a" into the current location in the buffer. Now we end up with the following:

1: char array[3][2];
2:
3: array[0][0] = 'x';

4: array[1][0] = 'z';
5: array[2][0] = 'y';
6: array[0][1] = 'y';
7: array[1][1] = 'z';
8: array[2][1] = '\n';

To clear the register, issue this command:

:let @a = ""

0 comments:

Release 7.0; Copyright © 1996-2012 Aaron Klotz. All Rights Reserved.