The "dot" Command in Vim

jovica profile image jovica ・3 min read

I believe you have already heard of the principle Don’t Repeat Yourself.

In software engineering, this is a principle of software development where your focus is on reducing repetition of all kinds. As you'll see throughout the book, Vim has many ways and commands to automate different kinds of tasks, so you don't have to repeat your actions.

One of the most powerful Vim command when it comes to avoiding repetition is the . ("the dot") command.

Hitting . in Normal mode will repeat the last native Vim command you've executed.

Let's say you want to delete 5 words from the cursor forward. As you already know, you could press 5dw and it's done. However, sometimes it's not convenient to mentally count the number of words.

An alternative would be to use dw to delete one word. And then press .... to call the dot command four times. In this case, you would repeat the latest, dw command, four more times, and in this way achieve the same effect without counting the words.

If you used dd to delete a line, and you want to delete 4 more lines, you could also execute 4. instead of pressing .... . That also works.

It's very important to understand what is actually repeatable by the dot command. For example, if you have a sample code like this:

my $i
my $learn
my $quickly

and your cursor is positioned on the first line. You want to append ; to all three lines. You could run a command like: A;<Esc>j

A – would place your cursor at the end of the first line in Insert mode.
; – you press to actually insert it, and then you press Esc to get back to Normal mode.
j – to move one line down

Now, your cursor is at the second line. If you then press . to repeat the change in next (second) line, this won't work. Here's what you'd get:

my $i;
my $learn;
my $quickly

Your cursor will still be at the second line rather than on the third line, but ; will be appended.

This brings us to conclusion that only this part of our original command was repeated: A;<Esc>.

Now, why is this the case?

It’s important to remember that with the dot command, you can repeat the commands which change the contents of the buffer.

A change is any command which you can use to modify your text. In our example, we had the case that command j wasn't repeated, and our cursor wasn't moved to the third line.

Commands like j are called motions (or nouns)—and they don't affect the text itself. Command j just moves the cursor, but doesn't change text anyhow, so it can't be repeated.

Think in terms of the grammar of your native language: Not nouns, but verbs are used to express some sort of action. The same is true in Vim: nouns (or motions) can't affect the text, so they can't be repeated with the dot command.

To see all the commands which can affect the text in a buffer, take a look at :help change.txt

Of course, if you'd like to repeat multiple changes, or a combination of movements and changes, you can easily record those into a macro.

You can learn all you need on macros from Macros chapter (free to download) of my book Mastering Vim Quickly: From WTF to OMG in no time.

Still reading?

Every Tuesday I send awesome tips on Vim to 6K+ Vim fans, subscribers of my Mastering Vim Quickly Newsletter. Join us for free.

This post was originally published on my blog.


Editor guide
blayne profile image

Macros are great if you want to repeat commands every now and then, but I find norm to be more convient for editing consecutive lines plus it's much faster over many lines.

:%norm A;

Will add a semicolon to the end of every line. Norm can be combined with other movement commands like:

:1,4norm f ;d0x

For the first 4 lines (or next 4 lines depending on what line mode you are in) deletes from the the second space to the beginning of a line then deletes the space.

fidelve profile image
Fidel Sanchez-Bueno

for anyone interested in what would be the macro for doing this, let's say we have this lines:

this line
this other line
this line also

First, we move to the first line and type qa this will begin recording the macro (you will see at the bottom recording @a), then we type A;<ESC>jq, the q at the end will end the recording of the macro, and the macro that got recorded was A;<ESC>j.

After that to repeat the macro we type @a (and after that first one we can continue with @@ if we want).

scriptmunkee profile image
Ken Simeon


Absolutely brilliant!
I don't know how I've never known about the . command.

kmyokoyama profile image
Kazuki Yokoyama

Nice article! I'm curious about how you could perform it (appending semicolon) on multiple lines idiomaticly.

ythalorossy profile image
Ythalo Rossy Saldanha Lira

Perfect explanation!
Thanks so much.

stoeffel profile image
Christoph Hermann

I just wrote something very similar to this (well much shorter and more of a cheat sheet) :-)