Skip to main content

Advanced Motions

Beyond basic hjkl and word jumps, Neovim has a rich set of jump-based navigation features for moving precisely through large files and multiple files.

Learning Focus

These motions separate beginner Vim users from expert ones. Master the jump list, marks, and % matching to navigate codebases without plugins.

The Jump List

Every time you make a "large" jump (search, G, gg, %, etc.), Neovim records the position in the jump list.

KeyAction
Ctrl+oGo back (older) in jump list
Ctrl+iGo forward (newer) in jump list
:jumpsShow the jump list
tip

Ctrl+o is like a "back" button for your cursor. After following a search match or Go-to-Definition, press Ctrl+o to return.

The Change List

Neovim also tracks each position where you made a change:

KeyAction
g;Go to previous change position
g,Go to next change position
:changesShow the change list

Marks

Marks are named bookmarks within files:

Setting Marks

m{a-z}     → Set lowercase mark (file-local)
m{A-Z} → Set uppercase mark (global — across files)

Jumping to Marks

`{mark}    → Jump to exact position of mark
'{mark} → Jump to start of line of mark
`` → Jump back to position before last jump
`. → Jump to last change position
`^ → Jump to last insert-exit position
`[ → Jump to start of last yank/change
`] → Jump to end of last yank/change
`< → Jump to start of last visual selection
`> → Jump to end of last visual selection

Listing Marks

:marks         → Show all marks
:marks abc → Show marks a, b, c

Practical Mark Workflow

1. At position A: ma
2. Navigate far away
3. Return with: `a

For cross-file:
1. In file1.lua: mA (uppercase = global)
2. Open file2.lua, make changes
3. `A → instantly back to file1.lua at exact position

The % Jump — Matching Delimiters

% jumps between matching pairs:

()    → jump between ( and )
[] → jump between [ and ]
{} → jump between { and }
/* */ → jump between /* and */
if/endif, do/end, etc. (in supported languages)
Practical uses:
Vi% → visual select everything inside matched braces
d% → delete from here to matching delimiter
y% → yank from here to matching delimiter

gd and gD — Go to Definition

Without plugins, Neovim provides basic definition jumping:

gd    → go to local definition (in current file)
gD → go to global definition (in file)

With LSP configured (Module 8), these become much more powerful.

Line Number Jumps

42G       → Go to line 42
:42 → Go to line 42 (command mode)
Ctrl+g → Show current file name and line number

Screen Position Jumps

H         → High — top line on screen
M → Middle line on screen
L → Low — bottom line on screen

Paragraph and Section Jumps

{         → Jump to previous empty line
} → Jump to next empty line
[[ → Jump to previous section/function start
]] → Jump to next section/function start
[] → Jump to previous section end
][ → Jump to next section end

[[ and ]] are language-aware in some filetypes.

Search-Based Navigation

/pattern          → Search forward
?pattern → Search backward
n → Next match
N → Previous match
* → Search word under cursor forward
# → Search word under cursor backward
g* → Search partial word under cursor forward
gn → Select next match (after search)
:noh → Clear search highlight

Search Patterns

/\<word\>         → Whole word only
/word\c → Case insensitive
/word\C → Case sensitive
/^word → Lines starting with "word"
/word$ → Lines ending with "word"
/\d\+ → One or more digits
/foo\|bar → "foo" or "bar"

Quickfix Navigation

Quickfix is a list of positions (from grep, compiler errors, LSP diagnostics). Navigate it with:

:cnext    :cn      → Next quickfix item
:cprev :cp → Previous quickfix item
:cfirst → First item
:clast → Last item
:copen → Open quickfix window
:cclose → Close quickfix window

From keymaps (configure these):

~/.config/nvim/lua/config/keymaps.lua
vim.keymap.set('n', '<leader>qn', ':cnext<CR>')
vim.keymap.set('n', '<leader>qp', ':cprev<CR>')
vim.keymap.set('n', '<leader>qo', ':copen<CR>')

What's Next