Vim controls: the knowledge and keys that matter
A practical guide to Vim’s modes, motions, operators, text objects, search, undo, registers and file navigation—without beginning with a wall of commands to memorise.
Vim starts making sense when you stop treating it like a normal editor
Vim is modal. The same key performs different work depending on the current mode, which is why the editor initially feels uncooperative if every key is expected to insert text.
Normal mode is where navigation and editing commands begin. Insert mode enters text. Visual mode selects text, and command-line mode accepts commands such as writing a file or running a substitution. Press Esc whenever the current state is unclear; it returns to Normal mode from the ordinary editing modes.
The status line normally shows modes such as -- INSERT -- or -- VISUAL --. Normal mode often has no mode label, so an apparently inactive editor may simply be waiting for a command.
Normal mode navigation and editing commands
i enter Insert mode before the cursor
v enter character-wise Visual mode
: enter command-line mode
Esc return to Normal mode
If unsure: press Esc once, then choose the next command.Enter Insert mode where the text needs to appear
The i command inserts before the cursor and a inserts after it. I and A move to the first non-blank character or end of the current line before inserting. These small distinctions remove unnecessary cursor movements.
Use o to open a line beneath the current one and O to open one above. They also enter Insert mode, making them more direct than moving to a line ending, pressing Enter and repairing indentation manually.
Insert mode supports ordinary typing and backspace, but Vim is designed around returning to Normal mode between changes. Staying in Insert mode and navigating with arrow keys is possible; it simply leaves most of Vim’s editing vocabulary unavailable.
i insert before the cursor
a append after the cursor
I insert at the first non-blank character
A append at the end of the line
o open a new line below
O open a new line above
Esc finish inserting and return to Normal modeMotions describe where a command should act
The h, j, k and l keys move left, down, up and right. They are useful for small adjustments, but word, line and search motions cover distance more effectively.
w moves to the start of the next word, b moves backwards and e moves to a word ending. The uppercase W, B and E variants treat punctuation-separated text as one whitespace-delimited WORD. Use 0 for the first column, ^ for the first non-blank character and $ for the end of a line.
gg moves to the first line and G to the last; a number followed by G moves to that line. Counts prefix most motions: 4j moves down four lines and 3w moves forward three words. This composability matters more than raw typing speed.
h j k l left, down, up, right
w b e next word, previous word, word end
W B E whitespace-delimited WORD motions
0 ^ $ column zero, first text, end of line
gg G first line, last line
42G line 42
% matching bracket, parenthesis or brace
f{char} find character on the current line
t{char} move just before that character
; , repeat that find forward or backwardOperators and motions form Vim’s editing grammar
Vim avoids providing a separate command for every editing situation. An operator describes what to do and a motion describes the range. d deletes, c changes and y yanks; combining d with w produces dw, deleting through a word motion.
Repeating an operator commonly applies it to the whole line: dd deletes a line, cc changes it and yy yanks it. Counts can apply to either part, so 3dd deletes three lines and d3w deletes across three word motions.
Change differs from delete because it enters Insert mode after removing the selected text. Use c when replacement is the intention and d when the next operation remains in Normal mode.
d + motion delete
c + motion change, then enter Insert mode
y + motion yank (copy)
dw delete to the next word boundary
d$ or D delete to the end of the line
cw change the current word from the cursor
y} yank to the next paragraph
dd / cc / yy operate on the current line
3dd delete three linesText objects target the thing around the cursor
Text objects let an operator act on a structural unit without first moving to one of its edges. iw means inner word while aw means a word including surrounding separation. The same inner-versus-around distinction applies to quotes, parentheses, brackets and braces.
ci" changes the contents inside double quotes while ca" also removes the quotes. di( deletes inside parentheses and ya{ yanks a brace-delimited block including its braces. The cursor only needs to be somewhere inside the object.
Text objects are one of the largest steps from using Vim as a keyboard-controlled editor to using its actual editing language. Learn a small set and combine them with d, c and y rather than memorising each combination as an unrelated shortcut.
iw / aw inner word / a word
i" / a" inside quotes / including quotes
i( / a( inside parentheses / including parentheses
i[ / a[ inside brackets / including brackets
i{ / a{ inside braces / including braces
ciw change the word under the cursor
ci" change text inside double quotes
da( delete the parenthesised expression
yi{ yank the contents of a brace-delimited blockUndo, repeat and paste make changes recoverable
Press u in Normal mode to undo and Ctrl-r to redo. Vim groups an Insert-mode session into a change, so returning to Normal mode at sensible points creates useful undo boundaries.
The dot command repeats the last change. A change might be ciw followed by replacement text, or an operator and motion. Design a repeatable change once, move to the next target and press . rather than recording the same keystrokes manually.
Deleted and changed text is placed in registers as well as yanked text. p pastes after the cursor or below the current line; P pastes before or above. Because deletion replaces the unnamed register, deleting immediately before a paste can overwrite the text you expected to paste.
u undo
Ctrl-r redo
. repeat the last change
p / P paste after or before the cursor
x delete the character under the cursor
r{char} replace one character
J join the next line to the current line
Example: ciwreplacement<Esc>
Move to another word and press . to repeat the replacement.Registers make copy and paste explicit
Vim stores text in named and numbered registers. The unnamed register, addressed as ", is used implicitly by ordinary delete, change, yank and paste operations. The 0 register keeps the most recent yank, which is useful after a later deletion has replaced the unnamed register.
Prefix an operation with "a through "z to select a named register. "ayy yanks a line into register a and "ap pastes it. Uppercase register names append instead of replacing, so "Ayy appends another line to register a.
System clipboard integration depends on the Vim build and environment. When supported, "+y and "+p use the + clipboard register. Check :version or :set clipboard? when clipboard behaviour differs between a terminal, remote host and graphical Vim.
"0p paste the most recently yanked text
"ayy yank the current line into register a
"ap paste register a
"Ayy append the current line to register a
"_d delete into the black-hole register
"+y yank to the system clipboard when supported
"+p paste from the system clipboard when supported
:registers inspect register contentsSearch is also a navigation system
Press / to search forwards and ? to search backwards. Enter submits the pattern, n moves to the next match in the same search direction and N moves in the opposite direction. * searches forwards for the word under the cursor and # searches backwards.
Search patterns use Vim’s regular-expression syntax, which differs in places from regular expressions used by Java or JavaScript. Start with literal searches, then use :help pattern when grouping, boundaries or escaping behaves unexpectedly.
Substitution uses the shape :[range]s/pattern/replacement/[flags]. Without a range it changes the current line. % selects the whole file, g replaces every match on each selected line and c asks for confirmation.
/account search forwards
?account search backwards
n / N next / previous match
* / # search for the word under the cursor
:nohlsearch clear search highlighting
:s/old/new/ replace first match on this line
:s/old/new/g replace every match on this line
:%s/old/new/g replace every match in the file
:%s/old/new/gc confirm each replacementFiles, buffers and windows are different things
A file is data on disk. A buffer is Vim’s in-memory representation of a file, which may contain unsaved changes. A window is a viewport showing a buffer, and a tab page is a layout containing one or more windows. Confusing these concepts makes commands such as :q and :bnext appear unpredictable.
:w writes the current buffer, :q closes the current window and :wq performs both. :q! abandons unsaved changes in that buffer, so use it deliberately. :e path opens a file in the current window.
:ls lists buffers, :bnext and :bprevious move between them, and :buffer name selects one. :split and :vsplit create horizontal and vertical windows; Ctrl-w followed by h, j, k or l moves between them.
:w write the current buffer
:q close the current window
:wq or ZZ write and close
:q! abandon changes and close
:e path edit a file
:ls list buffers
:bnext / :bprevious move through buffers
:split / :vsplit split the current window
Ctrl-w h/j/k/l move between windows
:qa close all windows
:qa! abandon changes and close everythingVisual mode, indentation and code editing cover the next layer
v begins character-wise Visual mode, V selects whole lines and Ctrl-v begins blockwise Visual mode. Move to extend the selection, then apply an operator. Visual mode is helpful while learning, although an operator and text object is often faster once the target can be described.
The > and < operators indent and outdent; >> and << apply them to a line. = asks Vim to reindent a range according to its filetype rules, and gg=G reindents the whole file. Whether that produces useful Scala formatting depends on the configured indentation support—it is not a replacement for the project formatter.
Macros record Normal-mode commands into a register. qa begins recording into register a, q stops and @a replays it. They are effective for a repeated edit that is too irregular for substitution, but the dot command is simpler for one repeatable change.
v character-wise Visual mode
V line-wise Visual mode
Ctrl-v blockwise Visual mode
> / < indent / outdent a motion or selection
>> / << indent / outdent the current line
= reindent a motion or selection
gg=G reindent the whole buffer
qa record a macro into register a
q stop recording
@a replay register a
@@ replay the most recent macroUse Vim’s own help instead of memorising everything
The essential skill is forming commands from a small grammar, not remembering a catalogue of shortcuts. Start with modes, useful motions, d/c/y, text objects, undo, dot and search. Add registers, windows and macros when a real editing task creates the need.
:help opens the manual and :help followed by a command goes to that subject. Some keys need notation: :help CTRL-W, :help text-objects and :help :substitute locate the window command, concept and command-line command respectively.
Run vimtutor in a terminal for an interactive introduction. Keep configuration modest while learning so advice and help match the editor in front of you. Add mappings only after understanding the operation they replace; otherwise a personalised setup can conceal the transferable Vim language.
- Press Esc when the current mode is unclear
- Think operator plus motion or text object
- Use u, Ctrl-r and . before manually repairing a change
- Prefer search and structural motions to repeated h, j, k and l
- Understand buffers and windows before installing navigation plugins
- Use :help and vimtutor as part of normal learning