The grammar of Vim
I’ve been a vi (and Vim) user for a long time. If you’ve never used Vim, it’s a delightfully anachronistic text editor that runs in a terminal. Even the “real app” is, for all intents and purposes, a terminal application. When I started working at Etsy, I doubled down on my Vim usage because Etsy provides all of its developers with a virtual machine running their own copy of the site where their development takes place. If you can stand to use a terminal-based editor, it makes life easy.
I had been using vi casually for at least 15 years, but relying on it for all my development work made it more important to vastly improve my Vim skills in a short time. The best article on Vim I read was Yan Pritzker’s Learn to speak vim — verbs, nouns, and modifiers! It totally revolutionized the way I thought about Vim.
If you’re not already a Vim/vi user (Vim is a fancy version of vi, which was created in 1979), the main thing you need to know is that it has two modes, one of which enables you to enter text as you would in any editor, and a command mode that enables you to perform operations on the text, move the cursor around and so forth. Mastery of vi is all about understanding command mode well enough to make up for the fact that you don’t have the use of the mouse or most of the features that are standard parts of other editors. The best vi users make users of regular editors look like they’re slogging through mud when they edit text.
I had always tried to learn new Vim techniques the same way you might learn a foreign language from a phrasebook — one combination of keystrokes at a time. Use “j” to move down a line. Use “cw” to change a word. Use “yy” to copy the current line into a buffer so that you can paste it elsewhere with “p”. You can get by this way, but it’s a very simplistic approach.
Advanced Vim users understand that the Vim interface is a language unto itself, and that the key to being productive is understanding Vim’s grammar. Pritzker accurately identifies that grammar as consisting of the following parts of speech: verbs, nouns, and modifiers.
The nouns usually represent positions within the document. For example, 0 (zero) represents the beginning of the current line. $ represents the end of the current line. j represents the next line in the file. When you use most nouns by themselves in command mode, the implied verb is “go to”. So if you type j you move to the next line. There are some exceptions. For example, in command mode, s means substitute a character. In other contexts, it’s a noun representing a sentence.
You can usually supply a quantity along with a noun. So 5j refers to the five following lines, and typing it will move your cursor down 5 lines if you don’t supply a verb. Likewise, the w noun represents a word, and moves to the next word to the right if you use it by itself. 3w moves three words to the right. Thinking of these as movement commands rather than as nouns in a grammar is limiting.
There are a couple of special nouns that I don’t see a lot of people using — f and t. f means “find the next occurrence” and t means “til the next occurrence” and both of them are applied to the next character you type. So typing f_ means “find the next underscore” (on the current line). t_ means “til the next underscore,” the cursor will stop on the character before the next underscore. (You can use F and T to search backward rather than forward.)
These are helpful for navigation, but they’re even more helpful when you’re constructing a complex editing command, because they can be used as a noun.
Now let’s talk verbs. The big three are y, d, and c. y is yank (copy). d is delete. c is change. Combining a noun and a verb applies the verb to the noun. That’s the essential grammar of a vi command. cw changes the current word. c0 changes the text between the cursor and the beginning of the line. d$ deletes to the end of the line.
Let’s look at f a bit more deeply. Say you have a variable named my_integer_value and you want to change the name to my_string_value. If you move to the beginning of the name and type cw you’ll change the entire variable name. Instead you can type fi to move to the “i” in “integer”. Then type ct_ (change up to the next underscore) and the word “integer” will be deleted. You can then type in “string” instead.
Lastly there are modifiers. Modifiers change how nouns are understood. The two big ones are i (inside) and a (around). Here’s a simple example. If your cursor is in the middle of a word and you use the command cw it will change all the characters from the cursor position to the end of the word. If you type ciw it will change the entire word. You can also use paired characters as nouns with i. So to change the contents of quotation marks, you can type ci”. Or to copy whatever is inside a pair of parentheses, you can type yi(. If you want to yank the parentheses themselves, you can use a instead — ya(.
This is just the tip of the iceberg. Once you know how to put these commands together, you’ll have a much easier time understanding the vi tips you see online. Suddenly you’re expanding your vocabulary rather than learning a new language.
For example, once you understand the grammar of vi, you can get a lot out of Andrei Zmievski’s Vim for Programmers presentation, which is a whirlwind tour through Vim commands that are particularly useful for PHP programmers.
vi is weird enough that it seems like it’s not worth the effort to learn. The problem is that to even get started, you have to learn the difference between the various modes and how to switch between them and you also need to learn the basic methods for navigating through a document. If you’re used to a normal GUI editor, that can be really frustrating.
A minimal amount of effort into learning vi will pay off for any Linux user, because you’ll be able to edit files in the terminal when you log into remote machines. I know you can also use Pico, but don’t do that. If you fall further into the world of Vim, you may find that it becomes the most powerful tool in your toolbox.
This story was originally published on rc3.org.