How to repeat the last change in Vim
How do you repeat an action in Vim?
Dot operator
You can repeat the last action by simply pressing .
(dot).
Let's have a look at the example. Imagine, you'd like to remove ;
from the end of the line in the following paragraph:
function f1() {}
function f2() {}
function f3() {}
function f4() {}
function f5() {}
One way to do this is to put the cursor on the first line, then press A<Backspace>Esc
. Then in order to repeat the same commands on the next line press j.
. Repeat on each line.
The dot operator worked here because it remembers everything you did, starting from getting into INSERT mode with A
and until you press Esc
to get back to normal mode. Whatever happened in the INSERT mode is considered as one indivisible operation.
The ;
operator
The ;
operator lets you repeat the f
, and t
motions. That comes handy when you need to replace a specific character, say single quotes with double quotes.
Here's another example,
Replace 'this' with 'that'.
You start at the beginning of the line, then f'r"
to move the cursor to the next occurrence of '
and replace it with "
. f'
is a motion, r"
is your dot-repeatable action.
That means that from now, you press ;.
to go to the next single quote and replace it with the double quote.
Macros
Sometimes, the set of actions that you need to repeat is not that trivial. In that case, you record a macro, which is simply a way to store and repeat whatever you press on your keyboard.
To record a macros press qa
. Here, you can use any other letter instead of a
- it's just a register, a pocket where you can put textual data.
Imagine, you have a set of JavaScript one-liner function you would like to change to arrow function:
function f1() { /* ... */ }
function f2() { /* ... */ }
function f3() { /* ... */ }
function f4() { /* ... */ }
function f5() { /* ... */ }
Expected:
f1 = () => { /* ... */ }
f2 = () => { /* ... */ }
f3 = () => { /* ... */ }
f4 = () => { /* ... */ }
f5 = () => { /* ... */ }
Press qa
to record a macro.
Then ^df<space>f(i<space>=<space><esc>f{i=><space>j
.
Then press q
to stop recording.
I know that looks like a bit too much, but there's nothing fancy going on here:
^
go to the beginning of the line (or rather to the first non-space character)df<space>
deletes the wordfunction
i<space>=<space><esc>
adds=
right before the first parenthesis in INSERT modef{i=><space>
adds=>
right before the body of the functionj
moves to the next line
If you get it right, now your cursor is on the next line, and you can pres @a
to play the macro again.
Or press 4@a
to play it four times, and thus change all remaining lines at once.
To wrap it up,
- Use
.
to repeat the last simple change. - Use
;
to repeat the lastf/F/t/T
motion. - For more complex cases, record a macro.
I hope that was helpful.
Have a productive day!