nblock's ~

Vim: substitute inside a visual selection

This is a short blog post on how to substitute text inside a visual selection with Vim. I encourage you to fire up a Vim instance and try it for yourself.

Suppose you have the following block of text:

x1 = do_something('a', 0x13, 0x02, 0x03, 0x02);
x2 = do_something('b', 0xab, 0xcd, 0xef, 0x01);
x3 = do_something('c', 0x15, 0x16, 0x17, 0x18);

and you want to refactor it to the following block of text:

x1 = do_something('a', 0x13020302);
x2 = do_something('b', 0xabcdef01);
x3 = do_something('c', 0x15161718);

Vim allows to substitute text using the s command. The substitute command operates on a range of lines and replaces the search pattern with a string. Vim also offers multiple visual modes (characterwise, linewise and blockwise visual mode) to visually select text and operate on it.

Starting with:

x1 = do_something('a', 0x13, 0x02, 0x03, 0x02);
x2 = do_something('b', 0xab, 0xcd, 0xef, 0x01);
x3 = do_something('c', 0x15, 0x16, 0x17, 0x18);

Place the cursor on the first line at the beginning of 0x13 and press CTRL-v to enable visual block mode and visually select all three lines up until the last parameter. All parameters starting with 0x should be selected.

Now, enter the following substitute command:

:<,>s/, 0x//g

Hit <CR> and notice that Vim produces the following result:

x1 = do_something('a'13020302);
x2 = do_something('b'abcdef01);
x3 = do_something('c'15161718);

This is not quite the result we expected. Vim's substitute command operates on lines of text and it substituted each occurrence of the pattern on all selected lines. Undo the substitution (by pressing u), reselect the visual selection by pressing gv and use the pattern-atom %V inside the substitute command:

:<,>s/\%V, 0x//g

Hit <CR> again and there it is:

x1 = do_something('a', 0x13020302);
x2 = do_something('b', 0xabcdef01);
x3 = do_something('c', 0x15161718);

The pattern-atom %V is used to match inside a visual selection. I encourage you to take a look at its documentation.

:h %V
:h pattern-atoms

Obviously, this is just one possible solution to solve this issue and many more exist. Until next time.


permalink

tagged vim