Vim Recipes Editing Selecting Text with Motions

Selecting Text with Motions

Problem

You want to define an area of text for a command to operate on without leaving Normal mode.

For example, you want to delete next two words, or reformat the current paragraph.

Solution

In Normal and Visual mode operator commands can be followed by motions which describe what text they should operate on. They can be thought of as a set of directions the operator should use to select text.

For example, you can delete the character under the cursor with x. If you wanted to delete the word fandangle you'd need to press x nine times: once for each character. You could simplify the process by prefixing x with a count: 9x. However, that requires you to know how many characters are in the word, and would be totally impractical if you wanted to delete multiple words at once. Instead you can use the dmotion command which deletes the text selected by motion, as opposed to the character-by-character approach of x. The motion for a word is w, so you can delete the word more easily with dw.

The following table shows some common operators which understand motions.

Operator Action Description
c change Deletes then enters insert mode.
d delete Deletes.
y yank Copies to a register.
gq format Reformats.
> indent Shifts text left.
< unindent Shifts text right.

Here are some common motions:

Command Moves
counth Left count characters.
countl Right count characters.
countj Down count characters.
countk Up count characters.
$ To end of the line.
count$ To end of the line count-1 lines downward.
0 To the first character of the line.
countfchar To the countth occurrence of char to the right.

We can combine operators and motions to select text then operate upon it. Let's look at some examples:

y10h
Copy the previous 10 characters to a register.
d$
Delete from the current character until the end of the line.
c2j
Delete the current line and the one below it, then enter Insert mode.

Discussion

Motions aren't very intelligent. Say you wanted to delete the word This with dw. That works as long as your cursor is over T; if you were on the h, you'd only delete that.

Vim supports additional motions for operating on text objects. One of these is aw (mnemonic: a word) which would do the right thing in both examples above because it considers what object, not character, the cursor over.

Text object commands are very similar to motions, and can be used with the same operators. They're frequently just a motion command prefixed with either a or i. The a prefix indicates that the whole object will be selected, including white space; the i prefix selects the inner object without white space, or just the white space. A few of the available commands follow:

Command Selects
countaw count words
countiw
countaW count non-blank characters
countiW
countas count sentences
countis
countaB count […] or {…} blocks
countiB
counta" count quoted strings
counti"

So, to delete a paragraph, position your cursor anywhere inside it then hit dap. Delete a paragraph - it even sounds sensibleNo, this is not a bug..

A motion can also be a regular expression, in which case it describes the text matched: extending from the current cursor position to the penultimate character matched by the pattern. The syntax is /pattern: a solidus followed by a regular expression. For example, d/\d deletes from the current character to the first digit, excluding the digit itself.