Vim Text Objects
Text objects for precise selection and manipulation.
Text Object Fundamentals
" TEXT OBJECTS = Semantic units of text
" Used with operators: d (delete), c (change), y (yank), v (visual)
" TWO TYPES:
" i = inner (inside, excluding delimiters)
" a = around (including delimiters)
" BASIC SYNTAX
{operator}{i|a}{object}
" EXAMPLES
diw " Delete inner word
daw " Delete a word (with trailing space)
ci" " Change inside quotes
ca" " Change including quotes
yi) " Yank inside parentheses
ya) " Yank including parentheses
" VISUAL MODE WITH TEXT OBJECTS
viw " Select inner word
vaw " Select word with space
vi" " Select inside quotes
va{ " Select including braces
" OPERATOR PENDING MODE
" Press d, c, y, or v, then vim waits for motion/text object
d " Operator pending... waiting
iw " ...inner word. Now executes
Word Objects
" WORD VS WORD
" word = sequence of letters, digits, underscores
" WORD = sequence of non-blank characters
" WORD OBJECTS
iw " Inner word
aw " A word (with trailing space)
iW " Inner WORD
aW " A WORD (with trailing space)
" EXAMPLE: "hello-world" is:
" - Two words: "hello" and "world" (hyphen is delimiter)
" - One WORD: "hello-world" (no spaces)
" USAGE PATTERNS
ciw " Change word (stay in same position)
daw " Delete word + following space
caw " Change word + space
yiW " Yank entire hyphenated/special word
" PRACTICAL: Change variable name
" Cursor on: myVariable
ciw " Change to newVariable
" Result: newVariable
" PRACTICAL: Delete argument
" Cursor on: func(arg1, arg2, arg3)
" Position on "arg2"
daw " Deletes "arg2, " (word + space)
" Result: func(arg1, arg3)
Sentence and Paragraph Objects
" SENTENCE OBJECTS
is " Inner sentence
as " A sentence (with trailing space)
" Sentence = ends with . ! ? followed by space or newline
" Great for prose editing
" PARAGRAPH OBJECTS
ip " Inner paragraph
ap " A paragraph (with trailing blank line)
" Paragraph = text separated by blank lines
" USAGE
cis " Rewrite sentence
das " Delete sentence
yip " Yank paragraph
dap " Delete paragraph + blank line
vip " Visual select paragraph
" PRACTICAL: Reformat paragraph
gqip " Re-wrap paragraph to textwidth
gqap " Re-wrap paragraph + blank line
" PRACTICAL: Move paragraph
dap " Delete (cut) paragraph
} " Move to next paragraph
P " Paste above
" PRACTICAL: Comment out paragraph
vip " Select paragraph
:'<,'>s/^/# / " Comment each line
Quote Objects
" QUOTE TEXT OBJECTS
i" " Inside double quotes
a" " Including double quotes
i' " Inside single quotes
a' " Including single quotes
i` " Inside backticks
a` " Including backticks
" EXAMPLES
" Cursor on: "hello world"
ci" " Change → |" (cursor between quotes)
di" " Delete → "" (empty quotes)
yi" " Yank → hello world (no quotes)
da" " Delete → (nothing, quotes gone)
" WORKS FROM ANYWHERE ON LINE
" Cursor: | "hello world"
" Doesn't matter where cursor is on line!
ci" " Still works - finds first quotes
" YAML/CONFIG EDITING
" Line: server: "localhost"
f" " Jump to quote (optional)
ci" " Change inside quotes
production.example.com<Esc>
" JSON EDITING
" Line: "hostname": "old-server",
2f" " Jump to value quotes
ci" " Change value
new-server<Esc>
" NESTED QUOTES (use 2i" etc)
" Line: "She said 'hello' to me"
2ci' " Change the second single quote pair
Bracket and Brace Objects
" BRACKET OBJECTS (all pairs work)
i) i( ib " Inside parentheses
a) a( ab " Including parentheses
i] i[ " Inside brackets
a] a[ " Including brackets
i} i{ iB " Inside braces
a} a{ aB " Including braces
i> i< " Inside angle brackets
a> a< " Including angle brackets
" ALL EQUIVALENT
di) " Delete inside parens
di( " Same
dib " Same (b = block/parens)
" PRACTICAL: Clear function arguments
" Cursor: function(arg1, arg2, arg3)
di) " Delete inside parens
" Result: function()
" PRACTICAL: Change array contents
" Cursor: [1, 2, 3, 4, 5]
ci[ " Change inside brackets
"new", "values"<Esc>
" PRACTICAL: Clear JSON object
" Cursor: {"key": "value", "other": 123}
di{ " Delete inside braces
" Result: {}
" NESTED BRACKETS
" Line: func(outer(inner))
ci) " Changes innermost around cursor
" To change outer: position cursor on 'outer' then ci)
" SELECT BLOCK INCLUDING BRACES
" Great for selecting function bodies
vaB " Visual select including braces
daB " Delete entire block
" MULTI-LINE BLOCKS
" {
" line1
" line2
" }
diB " Deletes all content between braces
daB " Deletes entire block including braces
HTML/XML Tag Objects
" TAG OBJECTS
it " Inside tag content
at " Including tags
" EXAMPLE
" <div>Hello World</div>
" Cursor anywhere in the line:
dit " Delete → <div></div>
cit " Change → <div>|</div>
yit " Yank → Hello World
dat " Delete → (entire tag gone)
vat " Visual select entire tag
" NESTED TAGS
" <outer><inner>Text</inner></outer>
" Cursor on "Text":
cit " Changes inner → <inner>|</inner>
2cit " Changes outer → <outer>|</outer>
" PRACTICAL: Clear HTML content
" <p class="description">Old text here</p>
cit " Change inside tag
New content<Esc>
" PRACTICAL: Delete HTML element
" <span class="old">remove this</span>
dat " Entire element deleted
" SELF-CLOSING TAGS
" <img src="photo.jpg" />
" it/at still work - select attributes
vit " Selects src="photo.jpg"
Custom and Plugin Text Objects
" BUILT-IN ADVANCED OBJECTS
" ARGUMENT OBJECT (via plugins like vim-argumentative)
" function(arg1, arg2, arg3)
cia " Change argument
daa " Delete argument with comma/space
via " Visual select argument
" INDENT-BASED (via vim-indent-object)
ii " Inner indentation level
ai " Around indentation (includes first line)
aI " Around indentation (includes surrounding blank lines)
" ENTIRE FILE
ie " Entire file (inner)
ae " Entire file (around, includes trailing newline)
" LINE OBJECT (via vim-textobj-line)
il " Inner line (no leading/trailing whitespace)
al " Around line (entire line)
" COMMENT OBJECT (via vim-textobj-comment)
ic " Inner comment (content only)
ac " Around comment (with delimiters)
" FUNCTION OBJECT (via vim-textobj-function)
if " Inner function body
af " Around function (with signature)
" POPULAR PLUGIN: targets.vim
" Adds: ci, (change inner next comma-separated),
" cin" (change inside next quotes)
" cil" (change inside last quotes)
" etc.
AsciiDoc/Documentation Text Objects
" ASCIIDOC EDITING PATTERNS (without plugins)
" CODE BLOCK SELECTION (source blocks)
" ----
" code here
" ----
" Position cursor on opening ----
V/^----$<CR> " Visual to closing delimiter
" Or use paragraph object if block is separated:
vip " Often selects code block
" ADMONITION BLOCK
" [NOTE]
" ====
" Content
" ====
" Inside admonition - use quote objects won't work
" Use line-based selection:
V}k " Visual select to end of block
" ATTRIBUTE REFERENCE
" {attribute-name}
yi{ " Yank attribute name
ci{ " Change attribute name
" XREF/LINK
" xref:page.adoc[Link Text]
f[ci[ " Change link text
f:ct[ " Change target
" LIST ITEM
" * Item one
" * Item two
" No built-in text object, but:
^d$ " Delete line content
0d$ " Same
" TABLE CELL (AsciiDoc uses |)
f|l " Move into cell
ct| " Change until next |
" SECTION (by delimiters)
" == Section Title
" Content here
V/^== \|\%$<CR> " Select to next heading or EOF
Operator Combinations
" DELETE + TEXT OBJECTS
diw " Delete inner word
daw " Delete around word
di" " Delete inside quotes
da{ " Delete around braces
dit " Delete inside tags
dip " Delete inner paragraph
" CHANGE + TEXT OBJECTS
ciw " Change inner word
ci" " Change inside quotes
cit " Change inside tag
cip " Change inner paragraph
caw " Change around word
" YANK + TEXT OBJECTS
yiw " Yank inner word
yi" " Yank inside quotes
yit " Yank inside tag
yap " Yank around paragraph
yaB " Yank around brace block
" VISUAL + TEXT OBJECTS
viw " Visual inner word
va" " Visual around quotes
vit " Visual inside tag
vip " Visual inner paragraph
vaB " Visual around braces
" FORMAT + TEXT OBJECTS
gqip " Reformat paragraph
gqap " Reformat around paragraph
" INDENT + TEXT OBJECTS
>ip " Indent paragraph
<ap " Outdent around paragraph
=ip " Auto-indent paragraph
" CASE + TEXT OBJECTS
guiw " Lowercase word
gUiw " Uppercase word
g~iw " Toggle case word
gUit " Uppercase tag content
Text Object Gotchas
" WRONG: Expecting aw to include preceding space
" daw includes FOLLOWING space (or preceding if at end)
" foo bar baz
" Cursor on "bar", daw deletes "bar " not " bar"
" CORRECT: Understand space behavior
" Inner = just content
" Around = content + TRAILING delimiter/space (usually)
" WRONG: Quote objects not finding quotes
" If cursor is before all quotes on line, won't work
" | "hello"
" Cursor at |, ci" fails (no quotes at or after cursor)
" CORRECT: Quotes are found forward from cursor
" Position cursor ON or AFTER opening quote
f"ci" " Jump to quote first
" WRONG: Nested bracket confusion
" ((a + b) * c)
" Cursor on 'a', ci) changes inner parens (a + b)
" ci( is the SAME as ci)
" CORRECT: For outer, position cursor appropriately
" Position cursor outside inner parens but inside outer
" WRONG: Tag objects in non-matching contexts
" <div>text</span> " Mismatched tags
" at/it behavior is undefined
" CORRECT: Ensure valid markup for tag objects
" WRONG: Expecting text objects to work across lines automatically
" Some text objects do (like ip, iB), some don't (like iw)
" CORRECT: Know which span lines
" SINGLE LINE: iw, aw, i", a", etc.
" MULTI-LINE: ip, ap, iB, aB, it, at, is, as
Quick Reference Table
| Object | Inner (i) | Around (a) |
|---|---|---|
Word |
|
|
WORD |
|
|
Sentence |
|
|
Paragraph |
|
|
Quotes |
|
|
Quotes |
|
|
Backticks |
|
|
Parens |
|
|
Brackets |
|
|
Braces |
|
|
Angles |
|
|
Tags |
|
|