Skip to main content

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

ModifierMnemonicWhat it includes
iinnerThe content, without surrounding chars
aaroundThe 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 ObjectSelects
iwInner word — the word without surrounding space
awAround word — word plus one surrounding space
iWInner WORD — space-delimited word without space
aWAround 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 ObjectSelects
isInner sentence
asAround sentence (including trailing space)
ipInner paragraph
apAround paragraph (including empty line)

Delimiter-Based Text Objects

These are the most productive text objects for code editing:

Text ObjectSelects 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 atHTML/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 ObjectSelects
i( / ibInner parentheses
a( / abAround parentheses
i{ / iBInner curly braces
a{ / aBAround 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

CombinationAction
ciwChange inner word
dawDelete around word
yi"Yank inner double-quoted string
ca(Change around parentheses
viBVisual inner Brace block
ditDelete inner HTML tag content
yapYank around paragraph
dipDelete inner paragraph
citChange inner tag (edit HTML content)
>aBIndent 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 {})

What's Next