Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: January 6, 2022
The vi editor is ubiquitous, especially in Linux and Unix environments. It’s useful to beginners, as well as power users.
In this tutorial, we discuss an advanced topic, namely text objects in vi. First, we go over the editor’s basic modes and operations. Next, we explore character groups and briefly explain the grammar of vi. After that, we see how basic text object operations are performed. Finally, we look at ways to create our own custom text objects.
Here, we use vi and Vi (editor) as aliases for both the Vi and Vim editors.
We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4. It is POSIX-compliant and should work in any such environment.
To reiterate, the Vi editor has three modes:
Immediately after the start, vi is in visual mode. To go into command mode, we use : (colon). On the other hand, with one of several characters such as i, a, and o, we can transition to insert mode. Finally, going back to visual mode is most commonly done via Esc (escape).
Of course, since its description defines it as a text editor, Vi supports many basic and easily-accessible capabilities.
For starters, we can visualize, traverse, write, delete. In addition, we might want to select, cut, copy, paste, search and replace.
While the first group can work with single characters, like regular editors usually do, the second one would be wasted on them. For example, we can use the arrow keys to move the cursor left and right by one character, but cutting and pasting a single character is rarely helpful.
To edit quickly, we might want to work on a logical group of characters. For instance, the text is often split into paragraphs. To that end, some common operations recognize groups of characters as text objects:
We already discussed single characters as the norm: they are easy to define and isolate. But, on the other hand, the boundaries for higher-order groups can be unclear.
Do we only use whitespace characters as word separators, or do any non-alphanumeric characters work as well? What’s a line ending?
The Vi editor spares us all these details by including operands, which help distinguish between such objects.
Apart from the character groups we already discussed, many operations in vi work on or with specific predefined objects:
These examples demonstrate the Vi editor’s grammar for text object operations. First, we have an action: here v for visual selection, y for yank/copy, c for change, d for delete.
After the action, we have a text object or a motion, which specifies what we act on. Let’s explore each.
In fact, all of the examples thus far used concrete surrounding characters to isolate parts of data. However, the Vi editor has many defined motions and text objects.
Importantly, we can explore the exact descriptions with the :help text-objects and :help object-motions commands within the editor.
While characters are just the atoms of text editing and thus most operations, there are motions that use them as markers for bigger actions. For example, we can use dt- (Delete To DASH) to delete everything up to the next dash.
We specify words with w:
Note how the first example distinguishes a word as a motion (pointer to a direction or position) versus the second using a word as the actual action text object.
Sentences use the character s. Furthermore, a sentence ends at a period, exclamation point, or question mark, followed by whitespace.
Indeed, to select this entire sentence, we just place the cursor on one of its words (from I to the ending) and use vis to get everything, excluding the trailing punctuation and whitespace.
In addition, there are the ( and ) motions, which allow us to use a command like d( to delete everything from the current cursor position to the beginning of the current sentence.
We work on paragraphs via p. They are surrounded by empty lines and usually benefit the most from the beginning and end markers.
For example, we can place the cursor at the comma in this sentence, and d} will leave only “For example”. All of the following text in the paragraph, including this sentence, will vanish.
What if we want to define a new text object?
Since vi supports scripting, we can create or simulate many complex behaviors. Furthermore, there is also an out-of-the-box mechanism for custom selections.
Scripting in the Vi editor is commonly done by adding lines to the vimrc configuration file:
xnoremap il g_o^
onoremap il :normal vil
In this example, we use xnoremap to map il in visual mode to the command g_o^. The latter instructs vi to:
The second line maps il in operator-pending mode to vil (now vg_o^) in normal mode. Thus, we have il for use like any other inside-command.
Alternatively, we can define objects on a per-session basis.
The Vi editor has 26 marks available. Each mark saves the current cursor position for future reference. We set marks with m, followed by a lower-case letter. Once set, we can use two commands in conjunction with a mark’s letter:
These combinations represent movements so that they can be used in other commands. For example, by marking the beginning and end of a custom text segment with ma and MB, respectively, we can `av`b to select it or `ad`b to delete it.
Actually, marks are much more versatile, so that we can use the :help mark-motions command to check them out in-depth.
In this tutorial, we explored text objects and how to use them in the Vi editor. While there are many, here is a good and concise vi cheat sheet, which covers much of what we discussed, as well as a lot more.
In conclusion, one can even play a game to learn the intricacies of this classical editor.