Vim's power comes from composable commands — but the learning curve is real. This reference covers every command you actually need, from the basics of not getting stuck to advanced macros and window splits.
Quick reference
The 30 commands that cover 90% of daily Vim work.
| Command | Mode | What it does |
|---|---|---|
i |
Normal | Enter Insert mode before cursor |
a |
Normal | Enter Insert mode after cursor |
Esc |
Insert/Visual | Return to Normal mode |
h j k l |
Normal | Move left/down/up/right |
w / b |
Normal | Forward/backward one word |
0 / $ |
Normal | Start/end of line |
gg / G |
Normal | First/last line of file |
dd |
Normal | Delete (cut) current line |
yy |
Normal | Yank (copy) current line |
p |
Normal | Paste after cursor |
u |
Normal | Undo |
Ctrl+r |
Normal | Redo |
/pattern |
Normal | Search forward |
n / N |
Normal | Next/previous match |
:%s/old/new/g |
Normal | Replace all in file |
x |
Normal | Delete character under cursor |
o / O |
Normal | New line below/above and enter Insert |
v |
Normal | Enter Visual mode (character) |
V |
Normal | Enter Visual mode (line) |
= |
Visual | Auto-indent selection |
:w |
Normal | Save file |
:q |
Normal | Quit |
:wq |
Normal | Save and quit |
:q! |
Normal | Quit without saving |
Ctrl+f / Ctrl+b |
Normal | Page down/up |
% |
Normal | Jump to matching bracket |
. |
Normal | Repeat last change |
ci" |
Normal | Change inside quotes |
>> / << |
Normal | Indent/unindent line |
* |
Normal | Search word under cursor |
The four modes
Understanding Vim's modes is the key to everything else.
| Mode | How to enter | What it does |
|---|---|---|
| Normal | Esc from any mode |
Navigate, delete, copy, run commands. Default mode. |
| Insert | i, a, o, s, and others |
Type text. Behaves like a regular editor. |
| Visual | v (char), V (line), Ctrl+v (block) |
Select text for operations. |
| Command-line | : from Normal |
File operations, search/replace, settings. |
The mental model: Normal mode is your base. You spend most time there, dipping into Insert mode only to type, and Visual mode only to select regions.
Navigation
Basic movement
h ← left
j ↓ down
k ↑ up
l → right
You can prefix any motion with a count: 5j moves 5 lines down, 3w moves 3 words forward.
Word and line movement
w forward to start of next word
W forward to start of next WORD (whitespace-separated)
b backward to start of previous word
B backward to start of previous WORD
e forward to end of current word
0 start of line (column 0)
^ first non-blank character of line
$ end of line
File navigation
gg go to first line
G go to last line
:42 go to line 42
Ctrl+f page forward (down)
Ctrl+b page backward (up)
Ctrl+d half-page down
Ctrl+u half-page up
H top of visible screen
M middle of visible screen
L bottom of visible screen
Jump list and marks
Ctrl+o go back to previous position (jump list)
Ctrl+i go forward in jump list
ma set mark 'a' at cursor position
`a jump to mark 'a' (exact position)
'a jump to line of mark 'a'
`` jump back to position before last jump
Editing
Entering Insert mode
| Command | What it does |
|---|---|
i |
Insert before cursor |
I |
Insert at start of line |
a |
Append after cursor |
A |
Append at end of line |
o |
Open new line below, enter Insert |
O |
Open new line above, enter Insert |
s |
Delete character and enter Insert |
S |
Delete line and enter Insert |
C |
Delete to end of line and enter Insert |
Deleting
| Command | What it does |
|---|---|
x |
Delete character under cursor |
X |
Delete character before cursor |
dd |
Delete (cut) current line |
D |
Delete to end of line |
dw |
Delete word forward |
db |
Delete word backward |
d$ |
Delete to end of line |
d0 |
Delete to start of line |
dG |
Delete to end of file |
dgg |
Delete to start of file |
d3j |
Delete 3 lines down (with current) |
All d commands cut to the default register — you can paste them back with p.
Copying (yanking)
| Command | What it does |
|---|---|
yy |
Yank (copy) current line |
yw |
Yank word |
y$ |
Yank to end of line |
y0 |
Yank to start of line |
yG |
Yank to end of file |
3yy |
Yank 3 lines |
Pasting
p paste after cursor (or below line for linewise)
P paste before cursor (or above line for linewise)
Changing (delete + insert)
| Command | What it does |
|---|---|
cc or S |
Change entire line |
cw |
Change word forward |
cb |
Change word backward |
ci" |
Change inside quotes |
ci( |
Change inside parentheses |
ci{ |
Change inside curly braces |
ca" |
Change around quotes (includes the quotes) |
ct, |
Change to next comma |
The pattern is c<motion> — any motion works.
Text objects
Text objects are the most powerful Vim concept for editing code.
| Object | Selects |
|---|---|
iw |
inner word |
aw |
a word (includes surrounding space) |
i" |
inside double quotes |
a" |
around double quotes (includes them) |
i' |
inside single quotes |
i( or ib |
inside parentheses |
i[ |
inside square brackets |
i{ or iB |
inside curly braces |
ip |
inner paragraph |
it |
inside HTML/XML tag |
Combine with operators: di( deletes everything inside (), yi{ yanks inside {}, vi" selects inside "".
Undo and redo
u undo last change
U undo all changes to current line
Ctrl+r redo
Search and replace
Searching
/pattern search forward for pattern
?pattern search backward for pattern
n jump to next match
N jump to previous match
* search forward for word under cursor
# search backward for word under cursor
:noh clear search highlight
Pattern is a regular expression. Case sensitivity:
:set ignorecase— case-insensitive search:set smartcase— case-insensitive unless pattern contains uppercase\cin pattern — force case-insensitive (e.g.,/\chello)\Cin pattern — force case-sensitive
Search and replace (substitute)
: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 file
:%s/old/new/gc replace all with confirmation (y/n/a/q/l)
:5,10s/old/new/g replace in lines 5 to 10
:'<,'>s/old/new/g replace in visual selection (auto-inserted)
Flags:
g— all matches on line (not just first)c— confirm each replacementi— case-insensitiveI— case-sensitive (overridesignorecase)
Special replacement patterns:
&— the entire match\1— first capture group\u— uppercase next character
Example — capitalize first letter of each word:
:%s/\b\(\w\)/\u\1/g
Visual mode
Selection types
v character-by-character selection
V line-by-line selection
Ctrl+v rectangular (block) selection
Visual mode operations
After selecting:
| Command | What it does |
|---|---|
d |
Delete selection |
y |
Yank selection |
c |
Change selection |
> |
Indent selection |
< |
Unindent selection |
= |
Auto-indent selection |
~ |
Toggle case |
u |
Lowercase |
U |
Uppercase |
: |
Enter command-line mode for selection |
Block editing (Ctrl+v)
Inserting text on multiple lines at once:
Ctrl+v— start block selection- Select the lines (with
j/k) I— insert mode at start of block- Type your text
Esc— text appears on all selected lines
Registers
Vim has named registers for storing text beyond the default clipboard.
"ayy yank line into register 'a'
"ap paste from register 'a'
"Ayy append line to register 'a' (capital = append)
"+yy yank to system clipboard
"+p paste from system clipboard
:reg show all register contents
The unnamed register "" is the default (always receives last d/y).
Register "0 always has the last yanked text (not deleted).
Register "+ is the system clipboard (requires clipboard support).
Macros
Macros record and replay sequences of commands.
qa start recording macro into register 'a'
q stop recording
@a replay macro 'a'
@@ replay last-used macro
5@a replay macro 'a' 5 times
Practical example — add a semicolon to the end of each line:
qa— start recordingA;— append semicolonEsc— back to Normalj— move to next lineq— stop recording100@a— replay 100 times
Windows and splits
Opening splits
:split or :sp horizontal split (same file)
:vsplit or :vsp vertical split (same file)
:sp filename horizontal split with file
:vsp filename vertical split with file
Ctrl+w s horizontal split
Ctrl+w v vertical split
Navigating splits
Ctrl+w h move to left window
Ctrl+w j move to window below
Ctrl+w k move to window above
Ctrl+w l move to right window
Ctrl+w w cycle through windows
Resizing splits
Ctrl+w = equal size
Ctrl+w > wider
Ctrl+w < narrower
Ctrl+w + taller
Ctrl+w - shorter
:resize 20 set height to 20 lines
:vertical resize 80 set width to 80 columns
Tabs
:tabnew open new tab
:tabnew file open file in new tab
gt go to next tab
gT go to previous tab
:tabc close current tab
:tabo close all other tabs
File and buffer operations
:w save
:w filename save as
:e filename open file
:e! reload file (discard changes)
:q quit
:q! quit without saving
:wq or :x or ZZ save and quit
:qa quit all windows
:ls or :buffers list open buffers
:b2 switch to buffer 2
:bd delete (close) buffer
:bn next buffer
:bp previous buffer
Useful settings (vimrc)
Add these to ~/.vimrc (Vim) or ~/.config/nvim/init.vim (Neovim):
" Display
set number " line numbers
set relativenumber " relative line numbers (great for motions)
set cursorline " highlight current line
set scrolloff=8 " keep 8 lines visible above/below cursor
" Indentation
set tabstop=4 " tab = 4 spaces
set shiftwidth=4 " indent step
set expandtab " use spaces instead of tabs
set autoindent " copy indent from previous line
" Search
set ignorecase " case-insensitive search
set smartcase " case-sensitive if uppercase in pattern
set hlsearch " highlight matches
set incsearch " incremental search as you type
" Usability
set backspace=indent,eol,start " backspace over everything in insert
set mouse=a " enable mouse
set clipboard=unnamed " use system clipboard
set undofile " persistent undo across sessions
6 common mistakes
1. Being stuck in Insert mode
If the screen is showing typed characters as commands (like kkkkjjjj), you're in Normal mode. Press u to undo, then remember: Esc to return to Normal from anywhere.
2. Using arrow keys instead of hjkl
Arrow keys work, but they also work in Insert mode — which lets you avoid learning hjkl. The problem: hjkl in Normal mode keeps your fingers on the home row, and motions like 5j or w only work in Normal mode anyway. Remap arrows in Normal mode to train yourself:
nnoremap <Left> :echo "Use h"<CR>
nnoremap <Right> :echo "Use l"<CR>
nnoremap <Up> :echo "Use k"<CR>
nnoremap <Down> :echo "Use j"<CR>
3. Repeatedly pressing h/l instead of using word motions
w, e, b, f, t are faster for horizontal movement. fX jumps to the next X character on the line, ; repeats it. tx jumps to just before x.
4. Using dd when you only want to delete to end of line
dd cuts the whole line. For "delete to end of line", use D or d$. For "delete word", use dw. dd is specifically for the whole line including the newline.
5. Forgetting that d, y, c all accept motions and text objects
Once you internalize d<motion>, you can delete to any position. dt) deletes to the next ). dap deletes the paragraph. d/foo<Enter> deletes to the next occurrence of "foo". Same for y and c.
6. Not using . (repeat last change)
The . command repeats whatever you last did in Normal/Insert mode — including text typed. This is extremely powerful for repetitive edits. Fix one thing with a compound command, then . on the next occurrence.
FAQ
What's the difference between Vim and Neovim?
Neovim is a modern Vim fork with built-in LSP (Language Server Protocol), Lua configuration, better defaults, and a larger plugin ecosystem. The core Vim commands and modes are identical. Start with Vim to learn the fundamentals; switch to Neovim when you want a full IDE setup.
How do I exit Vim?
:q to quit (fails if unsaved changes), :q! to quit without saving, :wq to save and quit, ZZ to save and quit (shortcut). If you're stuck in a mode, press Esc first, then type the command.
What is set nocompatible in vimrc?
It disables Vi compatibility mode, enabling Vim's full feature set. Modern Vim detects vimrc and sets nocompatible automatically, but adding it explicitly does no harm.
How do I copy to the system clipboard?
Use the + register: "+yy copies the line to the system clipboard, "+p pastes from it. Requires vim --version to show +clipboard. On many Linux systems, install vim-gtk or vim-gnome to get clipboard support. In Neovim, set clipboard=unnamedplus.
How do I search and replace with regex?
:%s/pattern/replacement/g uses the Vim regex dialect. Use \( and \) for capture groups (not ( and ) without \). In "very magic" mode (\v), regular regex syntax works: :%s/\v(\w+)/[\1]/g wraps each word in brackets.
What is the difference between :w and :wq?
:w saves without quitting. :wq saves and quits. :x is similar to :wq but only writes if the file was modified. ZZ in Normal mode is the same as :wq.