Searching#
Forward and backward search#
/pattern Search forward
?pattern Search backwardPress Enter to execute the search, then:
| Key | Action |
|---|---|
n | Next match (same direction) |
N | Previous match (opposite direction) |
Search for the word under the cursor#
| Key | Action |
|---|---|
* | Search forward for the exact word under cursor |
# | Search backward for the exact word under cursor |
These match whole words — searching on port won’t match export.
Search options#
" Case-insensitive search (add \c to any pattern)
/error\c
" Case-sensitive search (add \C to any pattern)
/Error\C
" Enable incremental search (highlights as you type)
:set incsearch
" Highlight all matches
:set hlsearch
" Clear current highlights
:nohlsearch
" or shorthand
:nohSearch and Replace (Substitution)#
The substitution command follows this format:
:[range]s/pattern/replacement/[flags]Common substitutions#
| Command | Effect |
|---|---|
:s/old/new/ | Replace first occurrence on current line |
:s/old/new/g | Replace all occurrences on current line |
:%s/old/new/g | Replace all occurrences in the entire file |
:%s/old/new/gc | Replace all, but ask for confirmation each time |
:5,10s/old/new/g | Replace on lines 5 through 10 |
:'<,'>s/old/new/g | Replace within visual selection |
Flags#
| Flag | Meaning |
|---|---|
g | Global — all matches on the line, not just the first |
c | Confirm each replacement |
i | Case-insensitive |
I | Case-sensitive |
n | Count matches without replacing |
Confirmation prompts#
With the c flag, Vim asks for each match:
| Key | Action |
|---|---|
y | Replace this match |
n | Skip this match |
a | Replace all remaining |
q | Quit substitution |
l | Replace this one and quit |
Regex Basics in Vim#
Vim uses its own regex flavor. A few things to know:
Characters that need escaping#
In Vim’s default “magic” mode, these are literal unless escaped:
| To match | Type |
|---|---|
( group ) | \( and \) |
+ (one or more) | \+ |
? (zero or one) | \? |
| ` | ` (or) |
{n,m} (quantifier) | \{n,m\} |
These work without escaping: . * ^ $ []
Very magic mode#
Prefix with \v to make all special characters work like standard regex (no escaping parens, plus, etc.):
" Standard Vim regex — escape everything
:%s/\(foo\|bar\)\+/replacement/g
" Very magic — cleaner
:%s/\v(foo|bar)+/replacement/gUseful patterns#
" Delete trailing whitespace
:%s/\s\+$//g
" Delete blank lines
:g/^$/d
" Add a semicolon to the end of every line
:%s/$/;/
" Replace multiple spaces with a single space
:%s/ \+/ /g
" Swap two words: foo bar → bar foo
:%s/\(foo\) \(bar\)/\2 \1/gCapture groups and backreferences#
Use \( and \) to capture, \1, \2, etc. to reference:
" Wrap each word in quotes
:%s/\(\w\+\)/"\1"/g
" Swap first and last name
:%s/\(\w\+\) \(\w\+\)/\2 \1/gThe Global Command#
:g executes a command on every line matching a pattern:
" Delete all lines containing "debug"
:g/debug/d
" Delete all blank lines
:g/^$/d
" Move all TODO comments to end of file
:g/TODO/m$
" Indent all lines containing "return"
:g/return/>The inverse — act on lines that don’t match:
" Delete all lines NOT containing "keep"
:v/keep/d
" equivalent to
:g!/keep/dJumping Between Locations#
Jump list#
Vim tracks where you’ve been. Navigate your history:
| Key | Action |
|---|---|
Ctrl-o | Jump back (older position) |
Ctrl-i | Jump forward (newer position) |
Searches, gg, G, and other big moves add to the jump list. Small moves like j, k, w don’t.
" View the jump list
:jumpsMatching brackets#
| Key | Action |
|---|---|
% | Jump to matching bracket: (), {}, [] |
Works for parentheses, braces, brackets, and with some plugins, HTML tags.
Line jumps#
| Command | Action |
|---|---|
42G or :42 | Go to line 42 |
gg | Go to first line |
G | Go to last line |
H | Top of visible screen |
M | Middle of visible screen |
L | Bottom of visible screen |
Marks#
Marks save a position you can return to later.
Setting marks#
ma Set mark 'a' at current position
mb Set mark 'b' at current positionLowercase marks (a–z) are local to the file. Uppercase marks (A–Z) are global across files.
Jumping to marks#
| Command | Jumps to |
|---|---|
'a | Line of mark a (first non-blank character) |
`a | Exact position of mark a (line and column) |
'' | Previous position (before last jump) |
`` | Exact previous position |
Special marks#
| Mark | Position |
|---|---|
'. | Last change |
'^ | Last insert |
'[ and '] | Start/end of last yank or change |
'< and '> | Start/end of last visual selection |
" List all marks
:marksPractical Workflows#
Find and replace a variable name with confirmation#
:%s/oldName/newName/gcReview each occurrence and press y or n.
Jump between function definitions#
/^function (search for functions at start of line)
n (next match)
n (keep going)Use marks to bounce between two locations#
ma (mark current position as 'a')
...navigate elsewhere...
mb (mark this position as 'b')
'a (jump back to mark a)
'b (jump back to mark b)Delete all lines matching a pattern#
:g/console\.log/dOperate on search results with gn#
gn selects the next search match. Combined with operators:
/pattern (search for something)
cgn (change the next match)
...type replacement...
Esc
. (dot repeats — changes next match)
. (and again)This is one of the fastest ways to rename something selectively.
Best Practices#
- Use
*and#to quickly search for the word under your cursor — faster than typing it out - Use
:noh(or map it to a key) to clear search highlights after you’re done - Prefer
\v(very magic) for complex regex to avoid escaping everything - Use
gn+ dot for selective replacements — more control than:%s///gcwhen you only need a few - Set marks at locations you return to frequently — they’re faster than searching each time
- Use
Ctrl-oliberally — it always takes you back to where you were

