vim — The Modal Text Editor for Efficient Editing
Practical guide to vim — the modal editor with normal, insert, visual and command modes for efficient text editing in the terminal.
vim is a highly configurable text editor built for efficient editing and available on virtually every Unix system. Its core is the modal concept: in normal mode you move around and run commands, in insert mode (entered with i) you type text, plus there are visual and command modes. This very design confuses beginners at first, but makes vim extremely fast once you get used to it. The essentials up front: Esc always brings you back to normal mode, :wq saves and quits, and :q! discards all changes and quits. This guide walks you through the commands that let you move around vim confidently – from the modes through navigation and editing to macros.
Modes
i — Enter insert mode at cursor position.
iI — Enter insert mode at the beginning of the line.
Ia — Enter insert mode after the cursor.
aA — Enter insert mode at the end of the line.
Ao — Open a new line below and enter insert mode.
oO — Open a new line above and enter insert mode.
OEsc — Return to normal mode from any other mode.
Escv — Enter visual mode (character selection).
vV — Enter visual line mode (line selection).
VCtrl+v — Enter visual block mode (column selection).
Ctrl+vR — Enter replace mode. Overwrite characters as you type.
RNavigation
h / j / k / l — Move left / down / up / right (one character/line).
5j (move 5 lines down)w — Jump forward to the start of the next word.
3w (skip 3 words)b — Jump backward to the start of the previous word.
be — Jump forward to the end of the current/next word.
e0 — Jump to the beginning of the line.
0^ — Jump to the first non-blank character of the line.
^$ — Jump to the end of the line.
$gg — Jump to the first line of the file.
ggG — Jump to the last line of the file.
G<n>G — Jump to line number n.
42G (go to line 42)Ctrl+f — Scroll one full page forward (down).
Ctrl+fCtrl+b — Scroll one full page backward (up).
Ctrl+bCtrl+d — Scroll half a page down.
Ctrl+dCtrl+u — Scroll half a page up.
Ctrl+u% — Jump to the matching bracket ({}, (), []).
%{ — Jump to the previous paragraph/blank line.
{} — Jump to the next paragraph/blank line.
}Editing
x — Delete the character under the cursor.
5x (delete 5 characters)dd — Delete (cut) the current line.
3dd (delete 3 lines)dw — Delete from cursor to the start of the next word.
dwd$ — Delete from cursor to the end of the line.
d$ (or D)d0 — Delete from cursor to the beginning of the line.
d0yy — Yank (copy) the current line.
3yy (copy 3 lines)yw — Yank from cursor to start of next word.
ywp — Paste after the cursor or below the current line.
pP — Paste before the cursor or above the current line.
Pu — Undo the last change.
5u (undo 5 changes)Ctrl+r — Redo the last undone change.
Ctrl+r. — Repeat the last editing command.
.r<char> — Replace the character under the cursor with the specified character.
ra (replace with 'a')cc — Change (replace) the entire line. Deletes and enters insert mode.
cccw — Change from cursor to end of current word.
cwc$ — Change from cursor to end of line.
c$ (or C)J — Join the current line with the next line.
3J (join 3 lines)>> — Indent the current line.
3>> (indent 3 lines)<< — Unindent the current line.
<<~ — Toggle the case of the character under the cursor.
~Search & Replace
/<pattern> — Search forward for a pattern.
/function?<pattern> — Search backward for a pattern.
?errorn — Jump to the next search match.
nN — Jump to the previous search match.
N* — Search forward for the word under the cursor.
*# — Search backward for the word under the cursor.
#:s/<old>/<new>/ — Replace the first occurrence on the current line.
:s/foo/bar/:s/<old>/<new>/g — Replace all occurrences on the current line.
:s/foo/bar/g:%s/<old>/<new>/g — Replace all occurrences in the entire file.
:%s/foo/bar/g:%s/<old>/<new>/gc — Replace all occurrences with confirmation for each match.
:%s/foo/bar/gc:noh — Clear search highlighting.
:nohFiles & Buffers
:w — Save the current file.
:w:w <filename> — Save as a different filename.
:w backup.txt:q — Quit (fails if unsaved changes exist).
:q:q! — Quit without saving (discard changes).
:q!:wq — Save and quit.
:wq (or ZZ in normal mode):x — Save and quit (only writes if changes were made).
:x:e <filename> — Open a file for editing.
:e config.php:e! — Reload the current file, discarding all changes.
:e!:bn — Switch to the next buffer.
:bn:bp — Switch to the previous buffer.
:bp:ls — List all open buffers.
:ls:b <n> — Switch to buffer number n.
:b 3Windows & Tabs
:sp <file> — Split window horizontally (optionally open a file).
:sp config.php:vsp <file> — Split window vertically (optionally open a file).
:vsp styles.cssCtrl+w w — Cycle between open window splits.
Ctrl+w wCtrl+w h/j/k/l — Move focus to the split in the given direction.
Ctrl+w l (focus right split)Ctrl+w q — Close the current split.
Ctrl+w qCtrl+w = — Make all splits equal size.
Ctrl+w =:tabnew <file> — Open a file in a new tab.
:tabnew index.phpgt / gT — Switch to the next / previous tab.
gt:tabclose — Close the current tab.
:tabcloseMarks & Jumps
m<letter> — Set a mark at the current cursor position (a-z local, A-Z global).
ma (set mark 'a')'<letter> — Jump to the line of the specified mark.
'a (jump to mark 'a')`<letter> — Jump to the exact position of the specified mark.
`a:marks — List all current marks.
:marksCtrl+o — Jump back to the previous location in the jump list.
Ctrl+oCtrl+i — Jump forward in the jump list.
Ctrl+iMacros
q<letter> — Start recording a macro to the specified register.
qa (record to register 'a')q — Stop recording the macro.
q@<letter> — Play back a recorded macro from the specified register.
@a<n>@<letter> — Play a macro n times.
10@a (run macro 'a' 10 times)@@ — Replay the last executed macro.
@@Useful Commands
:set number — Show line numbers.
:set number (or :set nu):set relativenumber — Show relative line numbers (for easier jumping).
:set relativenumber:set paste — Enable paste mode (disables auto-indent for pasting).
:set paste:set syntax=<lang> — Set syntax highlighting language.
:set syntax=php:set wrap / :set nowrap — Enable or disable line wrapping.
:set nowrap:!<command> — Execute an external shell command.
:!ls -la:r <file> — Read a file and insert its contents below the cursor.
:r header.html:r !<command> — Insert the output of a shell command below the cursor.
:r !date:%!<command> — Filter the entire file through an external command.
:%!sort (sort all lines):set hlsearch — Highlight all search matches.
:set hlsearch Conclusion
vim rewards the initial learning curve with enormous speed: once modes, motions and operators become second nature, you edit text almost without thinking – including macros, multi-occurrence substitutions and filtering through external commands. The most common stumbling block for beginners is the moment they feel "stuck": press Esc to reliably return to normal mode, then quit with :wq (save and quit) or :q! (discard all changes). Pay special attention to :%s/…/…/g, which replaces throughout the whole file – use the c variant (:%s/…/…/gc) when you want to confirm each match individually. For your first steps, vimtutor on the command line is the best practice.
Further Reading
- vim.org – official site – the project home page with documentation, downloads and help
- Vim help files online – the complete built-in vim documentation in a browsable form