Still, one of the best text editing tools in a console-only environment when speed and productivity matters.

Ctrl key shown as ^ throughout. N means an optional count before the command.

vim_logo

Open

vi file open file
vim file open file (vim)
vim -O f1 f2 split side by side
vim -o f1 f2 split stacked
vim -p f1 f2 open in tabs

From within vim:
:e file open another file
:vsp file vertical split with file
:sp file horizontal split with file

Close / Quit

:q quit
:qa quit all windows
:q! quit and discard changes
:qa! quit all and discard
:w save
:w file save as
:wq save and quit
:wqa save all and quit
:x save and quit (only if changed)
ZQ quit without saving (same as :q!)
ZZ save and quit (same as :x)

Splits and Windows

:sp horizontal split
:vsp vertical split
^w w cycle to next window
^w h j k l navigate to window left/down/up/right
^w < > shrink/grow horizontally
^w + - grow/shrink vertically
^w = equalize all windows
^w o close all but current

Movement

h j k l left, down, up, right
0 beginning of line
^ first non-blank character
$ end of line
w W next word / WORD
b B previous word / WORD
e E end of word / WORD
( ) previous / next sentence
{ } previous / next paragraph
gg top of file
G bottom of file
NG go to line N (e.g., 42G)
% jump to matching bracket
H top of window
M middle of window
L bottom of window

^b page up
^f page down
^u half page up
^d half page down
zz center cursor on screen
zt cursor to top of screen
zb cursor to bottom of screen

Search / Replace

/str search forward for str
?str search backward for str
n repeat search
N repeat search opposite direction
* search forward for word under cursor
# search backward for word under cursor
:noh clear search highlighting

: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 globally
:%s/old/new/gc replace globally with confirmation

Insert

i insert before cursor
a insert after cursor
I insert at beginning of line
A insert at end of line
o new line below, then insert
O new line above, then insert
Esc return to command mode
Ctrl-N autocomplete (next match)
Ctrl-P autocomplete (previous match)

Modify

d delete (cut), y yank (copy), c change (delete and insert)

dd yy cc current line
D delete to end of line (same as d$)
C change to end of line (same as c$)
d$ y$ c$ from cursor to end of line
d0 y0 c0 from cursor to beginning of line
d^ y^ c^ from cursor to first non-blank
dG yG cG from cursor to bottom of file
dgg ygg cgg from cursor to top of file
dw yw cw from cursor to start of next word
d3w y3w c3w next 3 words
3dd 3yy 3cc next 3 lines
d) y) c) to end of sentence
d} y} c} to end of paragraph

x delete character under cursor
X delete character before cursor
r{char} replace character under cursor
R replace mode (overwrite until Esc)
J join next line to current
~ toggle case of character under cursor
u undo
Ctrl-R redo
. repeat last change

Text Objects

Used after an operator (d, y, c) or in visual mode:

iw inner word
aw a word (includes trailing space)
iW inner WORD
i( i) inner parentheses
a( a) parentheses including brackets
iB inner curly braces
aB curly braces including brackets
i" inner double quotes
i' inner single quotes
it inner HTML/XML tag
at tag including tags

Examples:
ciw change inner word
di( delete inside parentheses
yi" yank inside double quotes
cit change inside tag

Visual Mode

v visual mode (character-wise)
V visual mode (line-wise)
Ctrl-V visual block mode (column-wise)
gv reselect last visual area
o in visual mode: move to other end of selection

In visual mode, highlight text then:
d delete, y yank, c change, x delete
~ toggle case, u lowercase, U uppercase
> indent right, < indent left

Cut / Copy / Paste

dd cut line
yy copy line
p paste after cursor
P paste before cursor
"ay yank into register a
"ap paste from register a
:reg show all registers

Macros

qa record macro into register a
q stop recording
@a replay macro from register a
@@ replay last macro
5@a replay macro 5 times

Marks

ma set mark a at cursor position
`a go to mark a (exact position)
'a go to mark a (first non-blank in line)
:marks show all marks
`` go to last jump position
Ctrl-O jump back in jump list
Ctrl-I jump forward in jump list

Settings

:set nu show line numbers
:set nonu hide line numbers
:set autoindent turn on auto-indent
:set tabstop=4 set tab width
:set expandtab tabs as spaces
:set hlsearch highlight search matches
:set nohlsearch turn off search highlighting
:set ignorecase case-insensitive search
:set smartcase case-insensitive unless uppercase used
:set wrap wrap long lines
:set nowrap disable line wrapping

To make settings permanent, add them to ~/.vimrc (e.g., set number).