Vim Cheat Sheet
Quick reference for Vim modes, movement, editing, search, and the commands developers use most.
Vim is a modal text editor with decades of muscle memory baked into its user base. Everything below assumes Vim 8+ or Neovim. The canonical reference is :help in-editor and vimhelp.org. For scripting, see Learn Vimscript the Hard Way.
Modes
Vim is modal: the same keys do different things in different modes.
| Mode | Purpose | Enter from Normal | Return to Normal |
|---|---|---|---|
| Normal | Navigation and commands | (default) | — |
| Insert | Type text like a regular editor | i, a, o, etc. | <Esc>, <C-[> |
| Visual | Select a region | v, V, <C-v> | <Esc> |
| Command-line | Ex commands, search | :, /, ? | <Esc> |
| Replace | Overwrite characters | R | <Esc> |
You spend most of your time in Normal mode. The single most important habit: hit <Esc> when in doubt.
Movement (Normal mode)
| Key | Moves |
|---|---|
h j k l | Left, down, up, right (one char) |
w | Forward to start of next word |
b | Backward to start of previous word |
e | Forward to end of word |
0 | Start of line |
^ | First non-blank of line |
$ | End of line |
gg | First line of file |
G | Last line of file |
:n | Line n |
{ } | Previous / next blank line (paragraph) |
% | Matching bracket / paren |
Ctrl-d | Half-page down |
Ctrl-u | Half-page up |
Ctrl-f | Page down |
Ctrl-b | Page up |
Most commands accept a count: 5j moves down five lines, 3w advances three words.
Editing
| Key | Action |
|---|---|
i | Insert before cursor |
a | Insert after cursor |
I | Insert at start of line |
A | Insert at end of line |
o | Open new line below and insert |
O | Open new line above and insert |
x | Delete character under cursor |
X | Delete character before cursor |
dd | Delete line (and copy it) |
dw | Delete word |
d$ | Delete to end of line |
cc | Change line (delete + insert) |
cw | Change word |
yy | Yank (copy) line |
yw | Yank word |
p / P | Paste after / before cursor |
u | Undo |
Ctrl-r | Redo |
. | Repeat last edit |
>> / << | Indent / outdent line |
J | Join next line with current |
d, c, y are operators — they combine with a motion: d2w deletes two words, y$ yanks to end of line.
Search and replace
| Command | Action |
|---|---|
/pattern | Search forward |
?pattern | Search backward |
n / N | Next / previous match |
* / # | Search for word under cursor (forward / backward) |
:s/old/new/ | Replace first match on current line |
:s/old/new/g | Replace all matches on current line |
:%s/old/new/g | Replace all matches in entire file |
:%s/old/new/gc | Replace with confirmation per match |
:%s/old/new/gci | Confirmation + case-insensitive |
Useful flags on the substitute command:
| Flag | Meaning |
|---|---|
g | All occurrences in the line |
c | Confirm each replacement |
i | Case-insensitive |
e | Suppress "no match" errors |
n | Report count, do not replace |
Visual selection
| Key | Selects |
|---|---|
v | Character-wise selection |
V | Line-wise selection |
Ctrl-v | Block (rectangular) selection |
Once in visual mode, the same movement keys apply. d, c, y, > work on the selection. Block selection is great for column edits — e.g. add a prefix to several lines at once.
Search regex differences
Vim's default regex dialect ("magic") differs from PCRE / JavaScript. Most special characters (*, +, ?, (, ), {, }, |) must be backslash-escaped to be active. Prepend \v ("very magic") to a pattern to flip this: most characters become special without escaping, so patterns look much closer to PCRE.
Equivalent syntax in each dialect:
| Feature | PCRE / JavaScript | Vim default (magic) | Vim \v (very-magic) |
|---|---|---|---|
| Capture group | (...) | \(...\) | (...) |
| One-or-more | + | \+ | + |
| Optional | ? | \? (or \=) | ? |
| Zero-or-more | * | * | * |
| Word boundary | \b | \< and \> | \< and \> |
| Lookahead/behind | (?=...) | not supported | not supported |
Alternation uses a pipe between branches — escaped in Vim's default mode, plain under \v:
" Vim magic: backslash the pipe. Matches "foo" or "bar".
:%s/foo\|bar/baz/g
" Vim very-magic: plain pipe, PCRE-like.
:%s/\vfoo|bar/baz/g
For complex patterns, \v is almost always clearer.
Windows and splits
| Command | Action |
|---|---|
:sp[lit] file | Horizontal split with file |
:vsp[lit] file | Vertical split with file |
Ctrl-w s | Split current buffer horizontally |
Ctrl-w v | Split current buffer vertically |
Ctrl-w h/j/k/l | Move focus left / down / up / right |
Ctrl-w H/J/K/L | Move window to the far edge |
Ctrl-w q / :q | Close current window |
Ctrl-w o | Close all other windows (only this one) |
Save and quit
| Command | Action |
|---|---|
:w | Write (save) current buffer |
:w file | Write to file |
:q | Quit (fails if unsaved changes) |
:wq | Write and quit |
:x | Write if modified, then quit |
:q! | Quit, discarding unsaved changes |
ZZ | Same as :x |
ZQ | Same as :q! |
Top 20 commands developers use
i " insert
Esc " back to normal
:w " save
:q! " force quit
u " undo
Ctrl-r " redo
dd " delete line
yy " yank line
p " paste
/pattern " search
n " next match
:%s///g " replace all in file
gg " top of file
G " bottom of file
0 " start of line
$ " end of line
w " forward word
b " backward word
. " repeat last edit
:e file " open file
Configuration tips
~/.vimrcis loaded on startup.:set nocompatiblethen:set relativenumberputs line numbers relative to the cursor line, which pairs well with5j-style counts.syntax onenables syntax highlighting.- For plugin management, modern setups use
vim-plugor Neovim's built-in:Lazy/:Packer. - Use
:help keywordto look up any command from inside Vim — for example:help :substitute.