The Power of Repetition
If Vim had a mascot, it would be the Dot Command (.).
The Dot Command simply does one thing: It repeats the last change.
This sounds trivial, but it changes everything. It turns editing into a game of golf: “How can I perform this edit in a way that the Dot Command can repeat it for me?”
⚡ What is a “Change”?
A “change” is any command that modifies the buffer.
dw(Delete word) → ChangeiHello<Esc>(Insert “Hello”) → Changedd(Delete line) → Changex(Delete character) → Changew(Move forward) → Not a change (Motion)y(Yank) → Not a change (Does not modify buffer)
1. The Ideal Edit
To maximize the power of ., you need to compose edits that are repeatable.
The Wrong Way
You want to append a semicolon ; to the end of the line.
$(Move to end)a(Append);(Type semicolon)<Esc>(Exit)
If you move to the next line and press ., what happens?
It just types ;. It does not move to the end of the line, because $ was a motion, not part of the change.
The Right Way
A(Append at End of Line);(Type semicolon)<Esc>(Exit)
Now, A is the operator (well, technically a command that implies motion+insert). If you move to the next line and press ., it jumps to the end and adds the semicolon.
[!TIP] Always prefer commands that combine motion and action (
I,A,C,s) over moving manually and then editing. They bundle the intent into a single repeatable unit.
2. The Dot Formula
The classic pattern for repetitive edits is:
Move + Dot
- Perform the first edit carefully.
- Move to the next target.
- Press
.. - Repeat steps 2-3.
Example: Deleting specific lines
Content:
Item 1
DELETED
Item 2
DELETED
Item 3
- Move to first “DELETED”.
- Type
dd(delete line). - Move to next “DELETED” (
jor/DELETED). - Press
..
3. Case Study: Refactoring a List
Imagine you have this raw data:
apple
banana
cherry
date
You want to turn it into a JavaScript array:
"apple",
"banana",
"cherry",
"date",
Strategy
We need to:
- Quote the word.
- Add a comma.
Step 1: The First Edit
^(Start of line) → Motion (ignored by dot)I(Insert at start) → Start Change"→ Type quote<Esc>→ End Change
Wait, that only adds the first quote. We want to do it all in one go.
Better Strategy: A and I are separate changes. We can’t do both in one dot command unless we use a macro or a smarter change.
The “Change Inner Word” Strategy:
ciw(Change Inner Word)"apple",(Retype the word with quotes - wait, that’s slow)
The Surround Strategy (Native Vim):
I"(Insert quote at start) →<Esc>A",(Append quote comma at end) →<Esc>
This requires two dot commands. One for the start, one for the end.
I"<Esc>j.j.j.(Apply to all)A",<Esc>j.j.j.(Apply to all)
This is still very fast.
4. Interactive Refactoring Challenge
Can you clean up this data using the Dot Command strategy?
Goal: Convert the list of names into a JSON-like format: name: "Value",