Vim Normal Mode
The Natural Resting State
Introduction
Normal mode is Vim’s natural resting state. Other text editors spend most of their time in something that resembles Insert mode. For those new to Vim, Normal mode might seem like a strange default. But experienced Vim users have difficulty imagining it any other way.
The Painter & The Brush
How much time do you think artists spend with their paint brushes touching the canvas? It varies from artist to artist, but surely not as much as off canvas. Think of all the things a painter does besides painting. They study the subject, adjust lighting, mix paints, etc.
A painter does not rest with a brush on the canvas, and so is with Vim. Painters spend a fraction of their time applying paint, programmers spend a fraction of their time writing code. Most of the time is spent thinking, reading, and navigating the codebase. And when we do want to apply changes, who says we have to switch to Insert mode? We can format existing code, duplicate it, move it around, or delete it all from Normal mode.
Chunk Undos
In other text editors, invoking the undo command after typing a few words might revert the last typed word or character. However, in Vim we can control the granularity of the undo command.
The u
key triggers the undo command, which reverts the most recent change. A
change can be anything that modifies the text in a document. That includes
commands triggered from Normal, Visual, and Command-Line modes, but a change
could also be any text entered or deleted in Insert mode.
In non-modal text editors, triggering the undo command after typing a few words could do one of two things. It could undo the last character that was typed. Or, more helpfully, it could chunk a set of characters together so that each undo operation removed a word instead of a character.
Compose Repeatable Changes
Vim is optimized for repetition. In order to exploit this, we have to be mindful of how we compose our changes. In Vim, we always have more than one way of doing something. In evaluating which way is best, the most obvious metric is efficiency: which technique requires the fewest keystrokes (a.k.a. VimGolf). But how should we pick a winner in the event of a tie?
Suppose that our cursor is positioned on the “d” at the end of the following line of text, and we want to delete the word “world”.
Delete Backward
Pressing db
deletes from the cursor’s starting position to the beginning of
the word, but it leaves the final “d” intact. We can delete this rogue character
by pressing x
. That gives us a Vim golf score of 3.
Delete Forward
This time let’s try deleting forward instead. We have to start by maneuvering
our cursor into position with the b
motion. Once it’s in place, we can excise
the word with a single dw
command. Once again, our Vim golf score is 3.
Delete an Entire Word
The daw
command is easily remembered by the mnemonic delete a word. We’ve
tried three different techniques for deleting a word: dbx
, dbw
, and daw
.
In each case, our Vim golf score is 3. So which is best?
Remember, Vim is optimized for repetition. Let’s go through these techniques again, but this time we’ll finish by invoking the dot command and see what happens.
The backward deletion technique involves two operations: db
deletes to the
start of the word and then x
deletes a single character. If we invoke the dot
command, it repeats the single character deletion. That’s not a big win!
The forward deletion technique also involves two steps. This time, b
is just a
plain motion, while dw
makes a change. The dot command repeats dw
, deleting
from the cursor position to the beginning of the line. There is no “next word”,
so in this context the dot command isn’t useful.
The final solution only invokes a single operation: daw
. This technique
doesn’t just remove the word, it also deletes a whitespace character. As a
result, our cursor ends up on the last character of the word “the.”. If we
invoke the dot command, it will repeat the instruction to delete a word. This
time, the dot command does something truly useful. The daw
technique invests
the most power into the dot command, and thus is the winner.
Making effective use of the dot command often requires some forethought. If you notice that you have to make the same small change in a handful of places, you can attempt to compose your changes in such a way that they can be repeated with the dot command. Recognizing those opportunities takes practice. But if you develop a habit of making your changes repeatable wherever possible, then Vim will reward you for it.
Simple Arithmetic
Most Normal mode commands can be executed with a count. We can use this feature
to do simple arithmetic. The <C-a>
and <C-x>
commands perform addition and
subtraction on numbers. When run without a count they increment/decrement by
one, but if we prefix a number, then we can add or subtract by any whole number.
For example, if we position our cursor on a 3
character, running 10<C-a>
would modify it to 13
.
Command | Description |
---|---|
<C-a> | Increment by 1 |
<C-x> | Decrement by 1 |
10<C-a> | Increment by 10 |
5<C-x> | Decrement by 5 |
The below is an example. Place your cursor on 10, then 90<C-a>
.
TIP: If your cursor is placed anywhere before 10
then 90<C-a>
will jump
forward to the first number instance and apply the operation.
Operators and Motions
Much of Vim’s power stems from the way operators and motions are combined. Take
for example d2w
which will delete two words. The operator here is d
for
delete. Followed by a count 2
, then the motion w
for word.
Vim’s Operator Commands
Operator | Description |
---|---|
c | Change |
d | Delete |
y | Yank into register |
g~ | Swap case |
gu | Make lowercase |
gU | Make uppercase |
> | Shift right |
< | Shift left |
= | Auto indent |
! | Filter {motion} lines through an external program |
The combination of operators with motions forms a kind of grammar. Learning new
motions and operators is like learning the vocabulary of Vim. If we follow the
simple grammar rules, we can express more ideas as our vocabulary grows. So
suppose that we already know how to delete a word using daw
and now we learn
about the gU
command. It’s an operator too, so we can invoke gUaw
to
uppercase all letters of the current word.
Or if we expand our vocabulary to include the ap
motion which acts on a
paragraph, then we find two new operations at our disposal. dap
to delete an
entire paragraph, or gUap
to make the whole paragraph shout.
Vim’s grammar has one more rule: when an operator command is invoked in
duplicate, it acts upon the current line. So dd
deletes the current line,
while >>
indents it. The gU
is a special case. We can make it act upon the
current line by running either gUgU
or the shorthand gUU
.
The Operator-Pending Mode
The Normal, Insert, and Visual modes are commonly known and identified by many
Vim users; however, only a few know about the Operator-Pending mode. We use it
dozens of times a day, and it usually lasts for a fraction of a second. For
example, we invoke it when we run the command dw
. It lasts during the brief
interval between pressing d
and w
keys.
If we think of Vim as a finite-state machine, then Operator-Pending mode is a state that accepts only motion commands. It is activated whenever we invoke an operator command, and then nothing happens until we provide a motion, which completes the operation. While Operator-Pending mode is active, we can return to Normal mode in the usual way by pressing escape, which aborts the operation.
Many commands are invoked by two or more keystrokes. For example, the g
, z
,
<Ctrl-w>
, or [
, but in most cases, the first keystroke merely acts as a
prefix for the second. These commands don’t initiate Operator-Pending mode.
Instead, we can think of them as namespaces that expand the number of available
command mappings. Only operator commands initiate Operator-Pending mode.
You might wonder why is an entire mode dedicated to those brief moments between invoking operator and motion commands, whereas the namespaced commands are merely an extension of Normal mode? Because we can create custom mappings that initiate or target Operator-Pending mode. In other words, it allows us to create custom operators and motions, which in turn allows us to expand Vim’s vocabulary.