How do I repeat an edit on multiple lines in Vim?
VimVim 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
- record a macro for one line, call it 'a'; in this case one types
> q a I , ESC j q
-
select the block of lines that you want to apply the macro to
-
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:
- Select text you want to apply the operator to using visual mode
- 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').