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

iw content

aw +space

WORD

iW content

aW +space

Sentence

is content

as +space

Paragraph

ip content

ap +blank line

Quotes "

i" content

a" +quotes

Quotes '

i' content

a' +quotes

Backticks

i` content

a` +backticks

Parens ()

i) ib content

a) ab +parens

Brackets []

i] content

a] +brackets

Braces {}

i} iB content

a} aB +braces

Angles <>

i> content

a> +angles

Tags

it content

at +tags