How do I repeat an edit on multiple lines in Vim?

Vim

Vim Problem Overview


I'm aware that in Vim I can often repeat a command by simply adding a number in front of it. For example, one can delete 5 lines by:

5dd

It's also often possible to specify a range of lines to apply a command to, for example

:10,20s:hello:goodbye:gc

How can I perform a 'vertical edit'? I'd like to, for example, insert a particular symbol, say a comma, at the beggining (skipping whitespace, i.e. what you'd get if you type a comma after Shift-I in command mode) of every line in a given range. How can this be achieved (without resorting to down-period-down-period-down-period)?

Vim Solutions


Solution 1 - Vim

Ctrl-v enters visual mode blockwise. You can then move (hjkl-wise, as normal), and if you want to insert something on multiple lines, use Shift-i.

So for the text:

abc123abc
def456def
ghi789ghi

if you hit Ctrl-v with your cursor over the 1, hit j twice to go down two columns, then Shift-i,ESC , your text would look like this:

abc,123abc
def,456def
ghi,789ghi

(the multi-line insert has a little lag, and won't render until AFTER you hit ESC).

Solution 2 - Vim

:10,20s/^/,/

Or use a macro, record with:

q a i , ESC j h q

use with:

@ a

Explanation: q a starts recording a macro to register a, q ends recording. There are registers a to z available for this.

Solution 3 - Vim

That's what the :norm(al) command is for:

:10,20 normal I,

Solution 4 - Vim

If you are already using the '.' to repeat your last command a lot, then I found this to be the most convenient solution so far. It allows you to repeat your last command on each line of a visual block by using

" allow the . to execute once for each line of a visual selection
vnoremap . :normal .<CR>

Solution 5 - Vim

I believe the easiest way to do this is

  1. record a macro for one line, call it 'a'; in this case one types

> q a I , ESC j q

  1. select the block of lines that you want to apply the macro to

  2. use the 'norm' function to execute macro 'a' over this block of lines, i.e.,

> :'<,'>norm@a

Solution 6 - Vim

I think the easiest is to record a macro, and then repeat the macro as many times as you want. For example to add a comma at the start of every line, you type:

q a I , ESC j q

to repeat that 5 times, you enter

5 @ a

Solution 7 - Vim

With your edit already saved in the . operator, do the following:

  1. Select text you want to apply the operator to using visual mode
  2. Then run the command :norm .

Solution 8 - Vim

Apart from the macros, as already answered, for the specific case of inserting a comma in a range of lines (say from line 10 to 20), you might do something like:

:10,20s/\(.*\)/,\1

That is, you can create a numbered group match with \( and \), and use \1 in the replacement string to say "replace with the contents of the match".

Solution 9 - Vim

I use block visual mode. This allows you to perform inserts/edits across multiple lines (aka 'vertical edits').

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsaffsdView Question on Stackoverflow
Solution 1 - VimrampionView Answer on Stackoverflow
Solution 2 - VimSvanteView Answer on Stackoverflow
Solution 3 - VimCyber OliveiraView Answer on Stackoverflow
Solution 4 - VimembossView Answer on Stackoverflow
Solution 5 - VimAlbertView Answer on Stackoverflow
Solution 6 - VimwimhView Answer on Stackoverflow
Solution 7 - VimNoahView Answer on Stackoverflow
Solution 8 - VimPaolo TedescoView Answer on Stackoverflow
Solution 9 - VimONODEVOView Answer on Stackoverflow