From characters and words to structure
Motions like w or $ are directional — they go somewhere from the cursor. Text objects are structural — they describe a region defined by what's around it. "Inside the parentheses," "around this word," "inside the HTML tag." The cursor can be anywhere within the region; Vim figures out the bounds for you.
The two prefixes
i= inner — just the content, no delimiters.a= around ("a" as in "a thing") — the content plus delimiters or surrounding whitespace.
So i" is "inside the double quotes," a" is "the double-quoted thing including the quotes."
The text objects you'll use a hundred times a day
Words and WORDs: iw / aw (treats punctuation as a boundary), iW / aW (only whitespace as boundary).
Quotes: i", a", i', a', i`, a`.
Brackets: i( = i) = ib (inside parens), i{ = i} = iB (inside braces), i[ = i], i< = i>. All have a variants that include the brackets themselves.
HTML / XML tags: it (inside tag — the content between <p> and </p>), at (around tag — including the tags).
Sentences and paragraphs: is / as, ip / ap.
ci" works the same whether your cursor is on the first character of the string, the last, or anywhere between. Vim scans outward to find the enclosing delimiters. This is why text objects are faster than visual selection: you don't position-then-select, you just name the region.Power combos you should burn into muscle memory
ci"— change inside double quotes ("rename a string").ci(— change inside parentheses ("rewrite the function args").ci{— change inside braces ("rewrite this block").cit— change inside HTML tag content.diw— delete this whole word.daw— delete this word and the trailing whitespace (so the rest of the line stays clean).dap— delete the entire paragraph.vi{— visually select inside braces (great for indenting blocks:vi{>).