level 04
Operators + Motions
The superpower: compose operators with motions and text objects.
This is the level people mean when they say Vim “clicked.” Everything so far was vocabulary. Here you start forming sentences. Operators combine with the motions and text objects you already know, so the number of edits you can express explodes — and you never had to memorize any of them. This is also home to Vim’s best idea, the one almost no other editor copied: text objects.
The Main Operators
d → delete (also cuts to register)
c → change (delete and enter Insert mode)
y → yank (copy)
> < = → indent, de-indent, auto-indent
Common Combinations
dw dd D → delete word / line / to end of line
cc C → change line / to end of line
yy → yank line
>> << == → indent / de-indent / auto-indent line
Text Objects: The Real Power
Text objects operate on semantic units. They take i (inner) or a (around):
iw aw → inner / a word
ip ap → inner / a paragraph
i" a" → inside quotes / including the quotes
i( a( → inside / including parentheses
i{ a{ → inside / including braces
it at → inside / including an HTML/JSX tag
Combine an operator with a text object and you describe an edit precisely: ci" means change the thing inside these quotes — no manual selecting required. ciw is the most-used rename command.
Delete with text objects
- With the cursor in
"Hello, world!", pressdi"— deletes inside the quotes; the quotes stay. - Undo, then press
da"— deletes the string including the quotes. - On the
numbersline, put the cursor inside[...]and pressdi[. - On the
userline, put the cursor inside{...}and pressdi{.
goal Feel the difference between i (inner) and a (around).
Change with text objects
- On
calculateTotal, pressciw, typecomputeSum, pressEsc. - On
pricein the parameter list, pressciw, typeunitPrice, pressEsc. - Inside the
(...)parameters, pressci(, typeitem, count, rate, pressEsc. - Inside the function body
{...}, pressci{and type a new body.
goal Use ciw to rename words and ci( or ci{ to replace delimited content.
Yank and paste with text objects
- With the cursor in
"localhost", pressyi"to yank the content. - Move to the empty
""indevConfig, pressci", thenCtrl+r "to paste the register, pressEsc. - Put the cursor in the first
{...}, pressyi{to yank the block. - Move to the second
{...}and pressci{thenCtrl+r ".
goal Copy and replace structured content with yi and ci.
Operators with motions
- On line 2, press
d2j— deletes the current line plus two below (three total). Counts onjreach that many lines down, sod2jspans three lines, not two. - Undo. On line 1, press
y2jto yank three lines, thenGandpto paste at the end. - On any line, press
>>to indent, then<<to un-indent.
goal Operators combine with counts and motions, not just text objects.
HTML / JSX text objects
- Inside the
<h1>content, presscit, typeHello World, pressEsc. - On the
<strong>element, pressdat— delete the entire tag. - Inside
"container", pressci"and typewrapper. - On the word
handleClick, pressciwand typeonButtonClick.
goal cit and dat operate on whole tags.
Challenge — refactor without the mouse
- Change
"John"to"Jane". - Change
"Doe"to"Smith". - Change the email to
"jane.smith@example.com". - Delete the
phoneNumberline withdd. - Change
"New York"to"Los Angeles".
goal All edits with text objects and operators only.
Capstone — reshape a function, operators only
The three const lines were copy-pasted and never finished — every one still reads req.body.id. Fix the whole function with operators and motions:
- Rename
handlertoupdateUser: cursor on the word,ciw, type it,Esc. - Line 2 keeps
.id. On line 3, put the cursor on the trailingidandciwit toname. On line 4,ciwthe trailingidtoemail. - Replace the response payload: cursor inside the
{ ok: true }, pressci{, typeid, name, email,Esc. - The function has no error guard. On the
const idline pressO, typeif (!req.body) return res.status(400).end();,Esc. - Grab the whole body in one stroke:
yi{yanks everything inside the function’s braces — confirm the register holds all the inner lines at once.
goal Compose text objects, counts, dot, and yank/paste into one clean refactor. No mouse, no Insert-mode navigation.