Vim Survival Guide
Enough Vim to edit confidently on any server — modes, motions, and the operator+motion grammar that makes it click.
Vim is modal. Normal mode is for moving and editing, Insert mode is for typing text, Visual mode selects, and : opens the command line. Most confusion comes from typing in the wrong mode, so press Esc whenever in doubt.
The rows assume the grammar that makes Vim fast: operator + count + motion or text object. d, c, y, > and gU are operators; w, }, t, and i" are what they act on. Learn one new motion and every operator can use it, and . repeats the whole change.
Modes & saving
- i · a · Esc
- insert before · append after the cursor · back to Normal mode
- I · A
- insert at the start · append at the end of the line
- o · O
- open a new line below · above, in Insert mode
- v · V · Ctrl-v
- visual select by character · by line · by block (columns)
- :w · :q · :wq · :q!
- save · quit · save and quit · quit discarding changes
- :x · ZZ · ZQ
- save only if changed, then quit · same · quit without saving
- :w !sudo tee %
- save a root-owned file you opened without sudo (Vim only, not Neovim)
- :e! · :sav new.txt
- revert to the saved file · save under a new name and switch to it
- E325 ATTENTION
- a swap file exists: another Vim has the file open, or one crashed — Recover or Delete
Move (motions)
- w · b · e
- next word · back · end of word;
W B Etreat any non-blank run as one word - 0 · ^ · $
- line start · first non-blank · line end
- gg · G · 42G
- top · bottom · line 42 (also
:42) - f x · t x · ; · ,
- jump to next x · till just before it · repeat · repeat backwards
- %
- jump to the matching ( ) { } [ ]
- { · }
- previous · next blank-line paragraph — fast vertical travel through code
- Ctrl-d · Ctrl-u
- scroll half a page down · up;
Ctrl-f/Ctrl-bscroll a full page - zz · zt · zb
- scroll so the cursor line sits in the middle · top · bottom
- H · M · L
- cursor to the top · middle · bottom of the screen
- Ctrl-o · Ctrl-i
- back · forward through the jump list — return after a search or
gg - gd · gf
- go to the local definition of the word · open the file path under the cursor
- ma · 'a · `a
- set mark a · jump to its line · jump to its exact position
- g; · gi
- jump to the last change · resume inserting where you last stopped
Edit (operator + motion)
- dd · dw · d$
- delete line · word · to end of line (
Dis short ford$) - x · r · J
- delete a character · replace one character · join the next line onto this one
- cw · cc · C
- change word · whole line · to end of line — delete, then Insert mode
- yy · p · P
- yank (copy) a line · paste after · paste before
- u · Ctrl-r · .
- undo · redo · repeat the last change — the most useful key in Vim
- d2w
- operator + count + motion: delete two words. Every operator composes with every motion
- >> · << · =
- indent · outdent · auto-indent (
gg=Gre-indents the whole file) - ~ · gUiw · guu
- toggle case · upper-case a word · lower-case a line
- Ctrl-a · Ctrl-x
- add · subtract 1 from the next number on the line;
5 Ctrl-aadds 5 - :earlier 10m
- rewind the buffer to 10 minutes ago;
:latergoes forward again
Text objects
- ciw · caw
- change inner word · the word plus its trailing space
- ci" · ci( · ci{
- change inside quotes · parentheses · braces, keeping the delimiters
- da( · yi{
- delete parentheses and contents · copy what is inside braces
- cit · dat
- change inside an HTML/XML tag · delete the whole element
- dap · yip
- delete a paragraph plus its blank line · copy just the paragraph
- cgn
- change the next search match; then
.repeats it on each following match
Search & replace
- /text · ?text
- search forward · backward;
n/Nfor next / previous match - * · #
- search forward · backward for the whole word under the cursor
- :%s/old/new/g
- replace in the whole file; add
cto confirm each,ito ignore case - :%s/\<old\>/new/g
\<and\>are word boundaries, soboldandolderstay untouched- :s/,/\r/g
- in a replacement
\rinserts a line break;\ninserts a NUL (shown as ^@) - :'<,'>s/a/b/g
- replace only inside the visual selection — press
:in Visual mode for the range - :g/pat/d · :v/pat/d
- delete every line matching · NOT matching the pattern
- :%norm A;
- run Normal-mode keys on every line — here, append a semicolon
- :noh
- clear search highlighting
- :set ic scs
- ignorecase + smartcase: case-insensitive unless the pattern has a capital
Registers & macros
- qa … q · @a
- record keys into register a · play them back;
@@repeats,10@aruns ten times - "ay · "ap
- yank into · paste from register a
- "0p
- paste the last yank — it survives later deletes, which overwrite the default register
- "_d
- delete into the black-hole register, leaving your yank intact
- "+y · "+p
- copy to · paste from the system clipboard (needs a Vim built with +clipboard)
- :reg
- show what every register holds
- Ctrl-r a
- in Insert mode, paste register a;
Ctrl-r "pastes the last yank or delete
Files, buffers & windows
- :e file · :ls · :b2
- open a file · list buffers · switch to buffer 2
- Ctrl-^
- toggle between the current and the previous file
- :sp · :vsp
- split horizontally · vertically;
Ctrl-w h/j/k/lmoves between windows - Ctrl-w o · Ctrl-w =
- close every other window · make all windows equal size
- :r !cmd · :%!cmd
- insert a command’s output · filter the whole file through it, e.g.
:%!jq . - :vimgrep /x/ **/*.py
- search a project;
:copenlists the hits,:cdoruns a command on each - vimdiff a b
- side-by-side diff;
]cnext change,do/dppull or push a hunk - :set paste
- stop auto-indent mangling pasted text on old terminals; modern Vim detects pastes itself
Recipes
Rename a variable in a file, confirming each match
:%s/\<count\>/total/gcThe word boundaries leave account and counter alone, and c asks before every change: y yes, n skip, a all the rest.
Turn a word list into a quoted, comma-separated list with a macro
qa start recording into register a
I"<Esc> insert a quote at the start of the line
A",<Esc> append a quote and a comma at the end
j move down a line
q stop recording
:2,$norm @a replay the macro on every remaining lineRecord the edit once on line 1, then :norm replays it line by line. Ending the macro with j also lets 99@a run it until the file ends.
Reformat JSON or sort lines without leaving Vim
:%!jq .
:'<,'>sort u
:%!column -tA ! filter replaces the lines with a command’s output, so any Unix tool becomes a Vim command; u undoes it if the tool fails.
Comment out a block of lines with block selection
Ctrl-v start a block selection on the first line
5j extend it down five lines
I# <Esc> type "# " once; Esc copies it to every lineBlock insert types on the first line and repeats on the rest when you press Esc. Use $A instead of I to append at ragged line ends.
Search and replace across a whole project
:vimgrep /oldName/ **/*.py
:copen
:cdo s/oldName/newName/g | update:cdo runs the substitution at every match in the quickfix list and update saves each changed file. Review the list in :copen first.
Questions about Vim Survival Guide Cheat Sheet
How do I exit Vim?
Press Esc to be sure you are in Normal mode, then type :q and press Enter. If Vim refuses because of unsaved changes, use :wq to save and quit, or :q! to quit and throw the changes away. In Normal mode, ZZ saves and quits in two keystrokes and ZQ quits without saving. With several files or windows open, :qa quits them all and :qa! does so while discarding everything. If the screen seems frozen, you may have pressed Ctrl-s, which pauses many terminals; Ctrl-q resumes output.
What is the difference between Vim and Neovim?
Neovim is a fork of Vim started in 2014. It keeps the same modal editing and nearly all of the same commands, so everything on this sheet works in both. The differences are in the plumbing: Neovim uses Lua for configuration and plugins, ships a built-in language server client and Tree-sitter parsing, and changed some defaults, while Vim continues with its own Vim9 script. A few old tricks differ; :w !sudo tee % does not work in Neovim. Choose Neovim for its plugin ecosystem, and plain Vim for being installed nearly everywhere.
How do I copy and paste between Vim and other programs?
Use the system clipboard register, written "+. In Normal mode "+y yanks into the clipboard and "+p pastes from it. This needs a Vim built with clipboard support: run vim --version and look for +clipboard, or install a fuller build such as vim-gtk or MacVim. To make every yank use the clipboard, add set clipboard=unnamed on macOS or Windows, or unnamedplus on Linux, to your vimrc. When you paste through the terminal instead, modern Vim detects the paste and stops auto-indent from mangling it.
What does the dot command do in Vim?
The dot key repeats the last change made in Normal mode, including the operator, its motion or text object, and any text typed in Insert mode. That makes it the core of efficient editing: make one change carefully, then move and press dot to apply it again. It pairs especially well with searching. Search for a word, change the next match with cgn, then press dot on each further occurrence you want changed and n to skip the ones you do not. This is why experienced users favor operators and text objects over Visual mode.