Text objects are a feature of the Vim text editor. They are used as a way
of specifying an operation's domain or scope. When used
correctly, text objects will confer several advantages upon the user, particularly when modifying existing text or code:
- Fewer keystrokes will be required for many common tasks.
- Less mental effort will be expended trying to come up with the correct
sequence of keys to press.
- The ease and speed with which seemingly complex operations can be
performed will dazzle any uninitiated observer. This can be a
subtle way of reminding a PHB or other mere mortal of their place; experimentation has shown that this cannot, however, be used to impress members of the fairer sex.
The idea behind text objects originates with vi. In vi's command mode
(which corresponds to Vim's normal mode, and which should not be confused with Vim's command mode which is known to vi users as ex mode), various commands are suffixed with a
sequence of keystrokes (often called a motion) which decide the command's
scope. For example, d$
will delete up to the end of the current
line and dfx
will delete up to and including the next
x
character on the current line. Similarly, c$
will
change up to the end of the current line and cfx
will change up to
and including the next x
character.
Most vi implementations also provide a w
motion, meaning word.
The cw
command will change up to the end of the current word, and
dw
will delete up to the end of the current word. Similar motions
also exist for working with characters, lines, sentences and paragraphs.
Sidenote: the cw
and dw
commands may behave
differently if a word is followed by whitespace; in most implementations, the
c
command will not delete the trailing space whereas d
will. This is often very useful and occasionally very annoying. There is even more variety in the behaviour of cw
if the
cursor is over a whitespace character — the original vi was buggy in this
respect, and different clones handled the issue differently.
Most motions can be used without a command. In this case, the cursor is moved
appropriately. A lone $
, for example, will move the cursor to the
end of the line.
It is also possible to specify a count before most motions. For example,
d2w
will delete two words, c3f.
will change up to and
including the third dot after the cursor and 5l
will move the
cursor right five characters.
Some commands — dd
and yy
are the most widely known — act upon an entire line when the command letter is repeated. The second character is not a regular motion in these cases.
Vim's text objects extend the motion concept to allow operations upon more
complex objects. However, text objects are only valid after a command
or when in visual mode (not to be confused with vi's visual mode) — partly this is because most of these commands
select text in both directions rather than simply forwards or backwards
from the cursor, and partly it is because nearly all of the keys available from
normal mode were already in use.
The first text objects introduced were not particularly ambitious. The
aw
object could be used to select a word including surrounding
whitespace, and iw
could be used to select a word ignoring
surrounding whitespace. Similarly, as
and is
select
sentences and ap
and ip
select paragraphs. These
motions are often more useful than the traditional vi motions, since they would
work as desired from anywhere in the word (or sentence, or paragraph)
rather than only at the start.
The a{
, a(
, a[
and
a<
objects (and their corresponding i
versions)
operate on blocks delimited by brackets. The a
variants include
the brackets in the selection, whereas the i
versions do not.
These objects are often useful when programming — they will behave
correctly across multiple lines and with nesting, offering considerably more
power than vi's nearest equivalents.
Version 7 of Vim (still in alpha at the time of writing) extends text
objects even further, bestowing the user with even greater power. New objects
have been introduced for quoted strings (including smart handling of escape
characters) and even HTML / XML style elements. The operators
are a"
, a'
and a`
for strings, and at
for tags; versions using i
are, as ever, also
available.