Vim motions: move by word, line and character

Stop pressing l twenty times. A motion is a command that moves the cursor, and Vim has one for nearly every place you want to go: the next word, the end of the line, the next comma, line 120, the matching bracket. This guide covers about thirty of them, and you can practise every one for free in the game.

Each example shows a line of text, the keys and where the cursor ends up. Columns are counted from 0, so the first character of a line is column 0. Vim's ruler starts at 1, so add one when you compare. Every example was replayed in the Vim engine that runs the game and checked in Neovim.

Characters and lines: h j k l and counts

h and l move one character left and right. j and k move one line down and up. They are on the home row, so your hands stay put.

Put a number in front of a motion to repeat it. On the quick brown fox, 4l moves four characters right, onto the q. Counts work with almost every motion in this guide, such as 3w, 5j and 2f, (jump to the second comma). The exceptions are G and gg, where the number is a line number, and 0, which takes no count.

j and k remember the column you started from. Start on column 12 of the first line here and press j twice:

LineCursor after
first line of textstart, on the f of of (column 12)
shortj: the last character, because the line is too short
third line of textj: back on column 12

Pressing a key more than twice in a row usually means there is a shorter motion.

Vim word motions: w, b, e, ge and WORDs

Vim has two ideas of a word:

Here is where each press of w lands on user.name = get_name(id);, starting at column 0:

user → . → name → = → get_name → ( → id → );

On the same line, W takes two presses to do what w did in seven: user.name → = → get_name(id);. Use w when you want to stop at punctuation, and W when you want to jump over a whole chunk like get_name(id);.

KeysMoves toFromLands on
wstart of the next wordu of user.
Wstart of the next WORDu of user=
eend of this or the next wordu of userr of user
Eend of this or the next WORDu of usere of name
bstart of this or the previous wordthe final ;)
Bstart of this or the previous WORDthe final ;g of get_name
geend of the previous wordg of get_name=
gEend of the previous WORDthe final ;=

w, b and e keep going across line breaks, so w at the end of a line takes you to the first word of the next one.

Line edges: 0, ^, $, g_

Take     return total;   , with four spaces of indent and three trailing spaces:

KeysMoves toColumn
0the very first column, inside the indent0
^the first non-blank character, the r of return4
$the last character, a trailing space19
g_the last non-blank character, the ;16

In code you almost always want ^ rather than 0, and g_ rather than $ when a line may have trailing spaces. 0 only works as a motion when no count is being typed: in 10j it is the second digit of ten.

Jump to a character: f, t, F, T, ; and ,

f followed by a character jumps onto the next copy of that character in the line. t jumps till it, stopping one column before. F and T do the same backwards. ; repeats the last one and , repeats it in the other direction.

On print("one", "two", "three"), starting at column 0:

KeysCursor lands onColumn
f,the first comma11
f,;the second comma18
f,;,back on the first comma11
t,the " just before the first comma10
t,;the " just before the second comma17
2f"the second quote, closing "one"10
$F"the last quote, closing "three"26

Notice t,;: after a t, Vim's ; skips the comma right next to the cursor and goes to the one after it, so repeating t does not get stuck. f and t only search the current line. To search the whole file, use / (see search in the cheat sheet).

Go to a line: gg, G and :N

KeysMoves to
ggthe first line
Gthe last line
42G or 42ggline 42
:42 Enterline 42, typed as a command

:42 is a command, so it needs Enter. 42G does the same in one key less. Line numbers start at 1, and :set number shows them on the left.

In Vim, gg, G and :42 land on the first non-blank character of the line, so you arrive on code, not on indentation. Neovim leaves the column unchanged, because its startofline option is off by default. Run :set startofline to get Vim's behaviour.

Paragraphs and brackets: {, } and %

Paragraphs. } jumps to the next empty line, and { to the previous one. In code that is usually the gap between two functions. A line that holds only spaces does not count as empty, so } goes straight past it. If there is no empty line below, } goes to the end of the last line.

Brackets. % jumps to the bracket that matches the one under the cursor. It works on ( ), [ ] and { }, across lines. If the cursor is not on a bracket, % uses the first bracket to its right on the line. Take this code:

if (items.length > 0) {
  send(items);
}
KeysFromCursor lands on
%column 0 of line 1the ) after > 0
$%column 0 of line 1the closing } on line 3
G%column 0 of line 1G goes to the } on line 3, then % to the { at the end of line 1

With a count, % means something else: 50% goes to the line halfway through the file.

Pick the motion with the fewest keys

Most places can be reached several ways. Counting keys is a good habit, and it is how Vimrealm scores every quest. Here the cursor starts on column 0 of const total = price * quantity; and the target is the q of quantity, column 22:

KeysCountComment
l pressed 22 times22what everyone does on day one
22l3short, but you have to count 22 characters first
wwwww5easy to see, slow to type
5w2you have to count words, and = and * are words too
fq2ties with 5w, but you do not have to count anything: you can see the q, and it is the only one on the line

A rule of thumb:

Motions are half of every edit

Everything above also works after an operator. d deletes, c changes and y copies over whatever the motion covers. In each row the cursor starts at column 0:

BeforeKeysAfter
user.name = get_name(id);dw.name = get_name(id);
print("one", "two", "three")f,d$print("one"
print("one", "two", "three")f(ldt)print()
print("one", "two", "three")f(ldf)print(
print("one", "two", "three")f"ct,"uno"<Esc>print("uno", "two", "three")

Read them as verb + motion. f,d$ moves to the comma, then deletes to the end of the line. In the last row, ct, changes everything till the comma, "uno" is the text you type, and Esc ends it. The t and f rows show the difference between the two: dt) stops before the ) and keeps it, while df) deletes it too.

Every new motion you learn is also a new way to delete, change and copy. That is why it pays to learn the motions first. The operators guide covers d, c, y and the case operators, text objects add targets such as "inside the quotes", and the dot command repeats the whole edit.

Real Vim has more

A few motions are worth knowing once these feel natural. Vimrealm does not teach them yet:

Every motion on this page, apart from the list above, is taught in chapters 1–5 of Vimrealm. They are free, with no sign-up. Each quest has a par, so you learn the short way, not just a way.

Play Vimrealm free

The free chapters: 1 Meadow of Motion (h j k l and counts), 2 Forest of Words (w b e ge W B E gE), 3 Cliffs of Line's End (0 ^ $ g_), 4 Seeker's Cave (f F t T ; ,), 5 Mountain of Lines (gg G :N { } %). Operators are in chapter 8, which is part of the full version ($7.99, one payment). See how the course works or keep the cheat sheet open while you practise.