Normal Mode Navigation
Navigation in Normal mode is the core of Vim's speed advantage. Every key is a movement command and they all compose with operators. The goal is to move with precision — never use arrow keys more than once.
Learn navigation in layers: character → word → line → screen → file → pattern-based. Practice each before moving to the next.
Layer 1: Character Navigation
h ← move left (one char)
l → move right (one char)
j ↓ move down (one line)
k ↑ move up (one line)
These were the arrow keys on the original ADM-3A terminal where Vi was created. They keep your hands on the home row.
Add counts for repeated movement:
5l → move right 5 characters
10j → move down 10 lines
Layer 2: Word Navigation
| Key | Motion |
|---|---|
w | Next word start (punctuation-aware) |
W | Next WORD start (space-delimited only) |
b | Previous word start (back) |
B | Previous WORD start |
e | end of current/next word |
E | End of current/next WORD |
ge | End of previous word |
Word vs WORD:
word= letters, digits, and underscores (breaks at-,.,(, etc.)WORD= any non-whitespace sequence (only breaks at spaces)
For: user-profile.avatar_url
w moves: user | - | profile | . | avatar_url
W moves: user-profile.avatar_url (treated as one WORD)
Layer 3: Line Navigation
| Key | Action |
|---|---|
0 | Go to column 0 (line start) |
^ | Go to first non-blank character |
$ | Go to end of line |
g_ | Go to last non-blank of line |
gj / gk | Move by display line (wrapped lines) |
f{char} | Find next occurrence of char on line |
F{char} | Find previous occurrence of char on line |
t{char} | Move to (one before) next char |
T{char} | Move to (one after) previous char |
; | Repeat last f/F/t/T forward |
, | Repeat last f/F/t/T backward |
f and t are extremely powerful
For: const result = calculateTotal(items, tax);
fa → jump to first 'a' (in calculate)
3f, → jump to 3rd comma
tf → move to just before first 'f'
Layer 4: Screen Navigation
| Key | Action |
|---|---|
H | High — top of screen |
M | Middle of screen |
L | Low — bottom of screen |
Ctrl+d | Scroll down half screen |
Ctrl+u | Scroll up half screen |
Ctrl+f | Scroll forward full screen |
Ctrl+b | Scroll back full screen |
Ctrl+e | Scroll line down (cursor stays) |
Ctrl+y | Scroll line up (cursor stays) |
zz | Center screen on cursor |
zt | Put cursor line at top |
zb | Put cursor line at bottom |
zz is incredibly useful — center the screen when you land on an important line.
Layer 5: File Navigation
| Key | Action |
|---|---|
gg | Go to file start |
G | Go to file end |
{N}G | Go to line N (e.g., 42G) |
{N}gg | Go to line N |
:42 | Go to line 42 (command mode) |
% | Jump to matching bracket/delimiter |
{ / } | Previous / next empty line (paragraph) |
( / ) | Previous / next sentence |
[[ / ]] | Previous / next section/function |
Layer 6: Pattern Navigation
| Key | Action |
|---|---|
/pattern | Search forward |
?pattern | Search backward |
n | Next match |
N | Previous match |
* | Search for word under cursor (forward) |
# | Search for word under cursor (backward) |
gd | Go to local definition |
gD | Go to global definition |
Search Tips
/error → find "error"
/\<error\> → find whole word "error"
/error\c → case-insensitive search
/^import → lines starting with "import"
/function.*{ → lines with function and {
# after search, clear highlight:
:noh (no highlight)
Jump List — Navigate Your Edit History
Neovim tracks where you jump. Navigate the jump list:
| Key | Action |
|---|---|
Ctrl+o | Go back in jump list |
Ctrl+i | Go forward in jump list |
:jumps | Show the jump list |
A "jump" happens when you: search, use G, gg, {N}G, %, or go to definition.
Position Marks
Save and return to specific positions:
ma → Set mark 'a' at current position
`a → Jump to exact position of mark 'a'
'a → Jump to start of line of mark 'a'
`` → Jump back to previous position
`. → Jump to last change position
`^ → Jump to last insert-exit position
Combining Navigation with Operators
Navigation commands become the motion in operator+motion combos:
d$ → Delete to end of line
y3j → Yank 3 lines down
c/foo → Change up to next "foo"
>} → Indent to next paragraph
vf; → Select to next semicolon
Common Navigation Pitfalls
| Pitfall | Better approach |
|---|---|
Using jjjjjj to move many lines | Use {N}j or /{pattern} |
Using hhhh to move many chars | Use f{char}, b, w, 0 |
| Using arrow keys | Use hjkl — keep hands on home row |
| Mouse-clicking to position | Use /{pattern} or {N}G |
Practice Exercises
1. Open any code file in Neovim
2. Practice: go to line 50 with 50G
3. Go back to previous position: Ctrl+o
4. Jump to a function with /function<Enter>
5. Navigate to the matching bracket: %
6. Center the screen on your cursor: zz