cody jh veal

Vim Killer Features Part 1: Text Objects

Written 3 years ago on February 9th, 2013

Vim has a notorious learning curve which often leads beginners to give up and return to a more traditional editor or IDE. I tried to learn Vim many times before I was able to fully embrace it, each time spending mountains of effort simply trying to get to parity with my productivity in other editors. While learning Vim will always require some frustration, a key insight is to find the killer features that no other editor will provide you. This is part one in a series of posts about features in Vim I couldn’t live without.

Imperative vs. Declarative Editing

Most common editors require navigating by mouse or keyboard to the end of a block of text and backspacing character by character before typing some new text. While often there is a way to do this word by word, or for an entire line (with modifier keys or multiple clicks in rapid succession) it is still a very imperative paradigm. We must tell the editor how to manipulate the text at a low level, instead of simply stating what we want done.

Vim’s modal paradigm instead works by providing us with a set of basic tools that we can compose in a very declarative manner. Vim extends the set of motions available to navigate around the file, for example } to move the cursor by paragraphs and fx to find the next occurrence of the character ‘x’. Ted Naleid and Michael Klein have come up with a great reference wallpaper for motions.

Vim also introduces operators which perform actions on blocks of text. For instance d is used to delete text and = can automatically correct indentation. Composing operators and motions is simple to do and can achieve powerful results. For instance we can use dG to delete the rest of a file from our current line, or cT to change text up to, (but not including) the previous double quote on the line. For more information see :help operator.

The Problem

While it’s certainly useful to have many more options to navigate around the file and perform actions on text, this method closely resembles the imperative workflow of other editors since we still need to navigate to the start and end of any region of text we wish to operate on.

To compound the problem, Vim movements are extremely unintuitive to the novice. There are many ways to move from point a to b, and determining the most efficient combination of keys to push requires understanding many movements and committing them to muscle memory. Navigating to the precise start and end of text blocks is not easy for Vim beginners, and even feels clumsy to all but seasoned Vim experts.

Introducing the Text Object

Luckily, Vim allows us to specify a block of text in a more intuitive way. Plain text is naturally broken up into words, sentences, and paragraphs. When programming, pieces of text are often delimited by punctuation, like array[indices], "strings", or <html>tags</html>. We can reference text that is grouped into logical chunks like this using Vim’s text objects. Any operator that takes a motion will take a text object instead. This lets us avoid having to navigate to the start and end of regions, we simply need to move the cursor anywhere within the region.

All text objects come in two forms, normal and inner (prefixed by a and i, respectively). As a general rule, normal text objects include the characters that delimit the object, while the inner form will leave the delimiters intact. The normal form is often used when deleting an object and the inner form is often useful for changing an object. For example, da will delete a double quoted string (perhaps to replace it with a variable), while ci will leave the quotes intact, and only delete the content inside the string, ready to be altered.

Built-in Text Objects

Vim comes bundled with a number of text objects defined. I’ve listed them below, but you can get more detailed descriptions of them by viewing :help text-objects.

User Text Objects

There are also a number of useful plugins which extend Vim’s built-in pool of text objects to power some very useful workflows.