How do I get more powerful text objects for quotes, brackets, and arguments in Vim?
Answer
cin)
Explanation
The targets.vim plugin dramatically expands Vim's built-in text objects by adding new selection modifiers, separator text objects, and argument text objects. It introduces the concepts of next, last, and seeking so you can operate on text objects even when your cursor is not inside them yet.
The problem targets.vim solves
Vim's built-in ci) only works when your cursor is already inside parentheses. If your cursor is before the parentheses on the same line, you have to navigate there first. Targets.vim fixes this by making text objects seek forward automatically.
New selection modifiers
Targets.vim adds two modifiers beyond the standard i (inner) and a (a/around):
ci) " change inside next pair of parentheses (seeks forward)
ca) " change around next pair of parentheses
cI) " change inside parentheses, excluding whitespace on both sides
cA) " change around parentheses, including surrounding whitespace
The I and A modifiers give you more precise control over whitespace handling.
Next and last pairs
Operate on the next or last (previous) occurrence on the current line without moving your cursor first:
cin) " change inside the NEXT pair of parentheses
cil) " change inside the LAST (previous) pair of parentheses
can) " change around the next pair of parentheses
cal) " change around the last pair of parentheses
Example
Given this code with the cursor at the beginning of the line (| marks cursor):
|var result = calculate(x + y);
With built-in Vim, ci) does nothing because the cursor is not inside parentheses. With targets.vim, cin) (or even just ci) since it seeks forward) changes the contents inside the parentheses, placing you in insert mode with:
var result = calculate();
Separator text objects
Targets.vim treats commas, dots, semicolons, pipes, and other separators as text objects:
ci, " change inside comma-separated item
ca, " change around comma-separated item (includes trailing comma)
ci. " change inside dot-separated segment
ci; " change inside semicolon-separated segment
ci| " change inside pipe-separated segment
ci_ " change inside underscore-separated segment
Argument text object
The plugin provides a dedicated argument text object a (for "argument") that understands nested brackets:
cia " change inside argument (the current function argument)
caa " change around argument (includes trailing comma and space)
daa " delete the current argument and its separator
Given function(first, second, third) with the cursor on second:
ciaselectssecondfor changingdaadeletessecond,resulting infunction(first, third)
Tips
- Targets.vim works with all operators:
d,c,y,v,gU,gu, and more - The seeking behavior means
ci"now works even when your cursor is before the quotes on the same line - All target text objects support counts:
c2in)targets the second next pair of parentheses - Pair targets.vim with vim-surround for maximum text manipulation power — targets handles the content, surround handles the delimiters