Text Objects
Text objects are the nouns of Vim's editing language. They describe meaningful chunks of text — words, sentences, paragraphs, quoted strings, parentheses blocks — that operators can act on.
Core Idea
Text objects let you act on semantic units of text without thinking about exact boundaries. ciw (change inner word) works wherever your cursor is inside the word — no need to navigate to the start.
Text Object Syntax
{operator} {i|a} {text-object}
i = "inner" (without surrounding whitespace/delimiters)
a = "around" (includes surrounding whitespace/delimiters)
The Two Modifiers: i and a
| Modifier | Mnemonic | What it includes |
|---|---|---|
i | inner | The content, without surrounding chars |
a | around | The content AND surrounding chars/whitespace |
Example with parentheses (hello world):
ci( → change inner ( → replaces "hello world", keeps parens
ca( → change around ( → replaces "(hello world)" including parens
di( → delete inner (
da( → delete around (
Word and WORD Text Objects
| Text Object | Selects |
|---|---|
iw | Inner word — the word without surrounding space |
aw | Around word — word plus one surrounding space |
iW | Inner WORD — space-delimited word without space |
aW | Around WORD — WORD plus surrounding space |
For: " hello world "
^^^^^ ← iw selects "hello"
^^^^^^^ ← aw selects "hello " (with trailing space)
For: user-profile.avatar
^^^^ ← iw (just "user")
^^^^^ ← aw (includes "-")
^^^^^^^^^^^^^^^^^^^← iW (entire "user-profile.avatar")
Sentence and Paragraph
| Text Object | Selects |
|---|---|
is | Inner sentence |
as | Around sentence (including trailing space) |
ip | Inner paragraph |
ap | Around paragraph (including empty line) |
Delimiter-Based Text Objects
These are the most productive text objects for code editing:
| Text Object | Selects inside... |
|---|---|
i" a" | Double quotes "..." |
i' a' | Single quotes '...' |
i` a` | Backticks `...` |
i( a( | Parentheses (...) — also ib |
i[ a[ | Square brackets [...] |
i{ a{ | Curly braces {...} — also iB |
i< a< | Angle brackets <...> |
it at | HTML/XML tags <tag>...</tag> |
Practical Code Examples
// function call: getData(userId, options)
// ^^^^^^^^^^^^^ di( → delete args
// ^^^^^^^^^^^^^^^ da( → delete args + parens
// string: const name = "Alice Smith"
// ^^^^^^^^^^^ ci" → change inner string
// ^^^^^^^^^^^^^ ca" → change including quotes
// array: const nums = [1, 2, 3, 4]
// ^^^^^^^^^^ yi[ → yank inner array
// ^^^^^^^^^^^^ da[ → delete including brackets
// object: const user = { name: "Bob", age: 30 }
// ^^^^^^^^^^^^^^^^^^^ viB → visual inner block
Block Text Objects
| Text Object | Selects |
|---|---|
i( / ib | Inner parentheses |
a( / ab | Around parentheses |
i{ / iB | Inner curly braces |
a{ / aB | Around curly braces |
B (uppercase) specifically means curly braces — useful for navigating function bodies:
ciB → change entire function body (keep braces)
daB → delete function body including braces
Text Objects with Operators
| Combination | Action |
|---|---|
ciw | Change inner word |
daw | Delete around word |
yi" | Yank inner double-quoted string |
ca( | Change around parentheses |
viB | Visual inner Brace block |
dit | Delete inner HTML tag content |
yap | Yank around paragraph |
dip | Delete inner paragraph |
cit | Change inner tag (edit HTML content) |
>aB | Indent around Brace block |
Text Objects Don't Require Precise Positioning
This is the key advantage — you can be anywhere inside the object:
"Hello World"
With cursor on 'l' in "Hello":
ci" → works! Changes "Hello World" to whatever you type
Nesting — Text Objects Find the Innermost Match
function outer() {
function inner() {
return getData(value); ← cursor here
}
}
diB → deletes "return getData(value);" (innermost {})
d2iB → deletes inner() function body (next outer {})