The Vim Grammar#
Vim commands follow a consistent grammar:
[count] operator [count] motion/text-objectOnce you learn a few operators and a few motions, you can combine them freely. This is what makes Vim scale — you’re not memorizing hundreds of commands, you’re learning a small set of composable pieces.
Operators#
Operators are the “verbs” — what you want to do to the text:
| Operator | Action |
|---|---|
d | Delete |
c | Change (delete and enter Insert mode) |
y | Yank (copy) |
> | Indent right |
< | Indent left |
= | Auto-indent |
gU | Uppercase |
gu | Lowercase |
An operator on its own does nothing. It waits for a motion or text object to tell it what to act on.
Motions#
Motions are the “nouns” — they define the range of text:
| Motion | Range |
|---|---|
w | Forward to start of next word |
b | Back to start of word |
e | Forward to end of word |
$ | To end of line |
0 | To beginning of line |
^ | To first non-blank character |
gg | To top of file |
G | To bottom of file |
f{char} | Forward to next {char} on current line |
t{char} | Forward to just before next {char} |
} | To next blank line (paragraph) |
{ | To previous blank line |
Combining Operators and Motions#
The power is in the combination:
| Command | Read as | Result |
|---|---|---|
dw | delete word | Deletes from cursor to start of next word |
d$ | delete to end of line | Deletes from cursor to end of line |
d0 | delete to beginning | Deletes from cursor to beginning of line |
dG | delete to bottom | Deletes from cursor to end of file |
cw | change word | Deletes word, enters Insert mode |
c$ | change to end of line | Deletes to end of line, enters Insert mode |
y3w | yank 3 words | Copies the next 3 words |
>} | indent to next paragraph | Indents all lines until next blank line |
gUw | uppercase word | Uppercases the current word |
Every new operator you learn works with every motion you already know.
Text Objects#
Text objects define structured regions of text. They always start with i (inner — excluding delimiters) or a (around — including delimiters):
| Text Object | Selects |
|---|---|
iw | Inner word (the word itself) |
aw | A word (word plus surrounding space) |
i" | Inside double quotes |
a" | Around double quotes (includes the quotes) |
i' | Inside single quotes |
i( or ib | Inside parentheses |
a( or ab | Around parentheses |
i{ or iB | Inside curly braces |
a{ or aB | Around curly braces |
i[ | Inside square brackets |
i< | Inside angle brackets |
it | Inside HTML/XML tag |
at | Around HTML/XML tag |
ip | Inner paragraph |
ap | A paragraph (includes trailing blank line) |
is | Inner sentence |
Text objects in action#
| Command | Result |
|---|---|
ciw | Change inner word (delete word, enter Insert mode) |
ci" | Change inside quotes (delete quoted content, stay in quotes) |
da( | Delete around parentheses (content + the parens) |
yi{ | Yank inside curly braces |
vat | Visually select around HTML tag |
>ip | Indent inner paragraph |
gUiw | Uppercase inner word |
Why text objects matter#
With motions, your cursor position matters. With text objects, you can be anywhere inside the target and it still works:
# Cursor is on the 'e' in "hello"
ci" → deletes "hello" and puts you in insert mode between the quotes
# Works regardless of where your cursor is inside the quotesCounts (Multipliers)#
Prefix any operator+motion with a number to repeat it:
| Command | Result |
|---|---|
3dw | Delete 3 words |
5dd | Delete 5 lines |
2yy | Yank 2 lines |
4j | Move down 4 lines |
3>} | Indent 3 paragraphs |
10iabc Esc | Insert “abc " 10 times |
Counts also work with d + count + motion:
d3w (delete 3 words)
3dw (same thing — delete word, 3 times)The Dot Command#
The . command repeats your last change. It’s the single most powerful efficiency tool in Vim.
# Change a word to "server"
ciw server Esc
# Move to another word you want to change the same way
w w w
# Repeat the change
.The dot command works with any operator+motion or text object combination:
# Delete inside parentheses
di(
# Find the next set of parens and repeat
f(
.Doubling an Operator#
Doubling an operator applies it to the entire current line:
| Command | Result |
|---|---|
dd | Delete line |
cc | Change line (delete and enter Insert mode) |
yy | Yank line |
>> | Indent line |
<< | Unindent line |
== | Auto-indent line |
gUU | Uppercase entire line |
f and t — Line-Level Precision#
f (find) and t (till) jump to a character on the current line:
| Command | Movement |
|---|---|
f; | Jump to next ; |
F; | Jump to previous ; |
t; | Jump to just before next ; |
T; | Jump to just after previous ; |
; | Repeat last f/F/t/T forward |
, | Repeat last f/F/t/T backward |
Combined with operators:
# Delete up to and including the next comma
df,
# Change everything up to (but not including) the closing paren
ct)
# Delete from cursor to the next equals sign
dt=Practical Examples#
Rename a variable#
# Cursor on the variable name
ciw newName Esc
# Find next occurrence and repeat
n .
n .Wrap content in parentheses#
# Select the text
viw
# Delete into register, type replacement
c(Ctrl-r ")EscReindent an entire function body#
# Cursor inside the function
vi{=Delete a function’s parameters#
# Cursor anywhere inside the parens
di(Change an HTML attribute value#
# Cursor anywhere inside the quotes of class="old-value"
ci"new-value EscBest Practices#
- Think in terms of operator + text object rather than character-by-character edits
- Learn
cianddicombinations first — they cover most editing needs - Use
fandtfor precise jumps on the current line instead of repeatedly pressingworl - Let the dot command do the repetition — make one good edit, then
.your way through - When an edit feels tedious, you’re probably not using the right text object — pause and think about what you’re actually trying to select

