As we speak the Vim language, we come to have a renewed appreciation for the great diversity of things that the compositional nature of language enables us to express. Just imagine if you couldn’t compose words to describe things in the real world, if there weren’t any distinctions between verbs and nouns and adjectives! Why, everything we’d want to say would be a unique word that we’d just have to memorize! That would be tedious indeed. On the other hand, composing words that have linguistic roles allows us to say so much with so little.
This is why we don’t have special hotkeys to delete the rest of the line from the current cursor position, or to insert something at the beginning of the line. We just say d$
and ^i
. How marvelous is the power of langua… wait a minute, we do have special hotkeys for these, they’re D
and I
. And, what about C
to change to the end of the line? And x
and s
! And S
and Y
for that matter… they’re everywhere. But… these aren’t “linguistic,” they’re… hotkeys. And if I’m just using hotkeys to do things, what separates me from the hordes of editor hotkey button mashers? What even AM I?? 😱
Whoa slow down there, take it easy, look, there’s no need for an existential crisis. It turns out that in any language, when expressions are common enough, we naturally invent shorthands for them that function identically to their more verbose representations. For instance, if we find ourselves rotating tiny metal caps on bottles against resistance to open them often enough, we invent a new word to describe this. We just twist the cap off. Likewise, 0i
and d$
are so common that we invent shorthands that mean the same thing as them. The key, defining quality of these shorthands is:
"this means what that means"
We don’t need to even say what “that” means at all. As long as we form an equivalence to an existing expression in the language, we can rest assured that the shorthand will be understood.
This habit, of defining new expressions that “mean the same thing as what that means” is called writing “macros” in programming languages in general, and in Vim in particular. And for the most common composite operations, Vim provides such shorthands or macros built-in. D
means what d$
means. I
means what ^i
means. I
and D
and C
and S
don’t follow linguistic structure because they are shorthands for phrases — they are essentially macros that come built-in.
While I
and D
express generally useful phrases, we often encounter situations where specialized phrases will be very common, or tasks where a specific phrase will be repeated many times. In such cases, we have another built-in macro to rely on — the handy .
(“dot”), which we learned about in the previous tip. Dot is essentially (as we are now in a position to see) an automatically maintained macro that always refers to your most recent command. But in some cases, dot isn’t enough, as the phrases are more complex than individual commands, or there may be more than one such phrase. We’d like to define our own shorthands, our own macros, to allow us to succinctly say these more complex phrases, which we may find to be common by virtue of the tasks we work on, or by virtue of our unique ways of thinking. How do we define these shorthands?
In general, by (1) describing how you would say it using the existing language, and (2) giving a name (“a new word”) to this new expression. In Vim:
- Remember a phrase, or “record a macro” —
q<name>
- As usual, a name can be any lowercase letter, like
a
- As usual, a name can be any lowercase letter, like
Once you’ve started defining a macro by pressing q
, Vim will indicate that it is “recording,” — this means that it is going to remember whatever you type until you stop the macro definition by hitting q
again. You are describing the new command using the existing Vim language. This includes any macros you may already have defined, although, unlike ordinary languages where new words and expressions may fulfill arbitrary linguistic roles (e.g. they could be used as verbs or nouns), Vim macros are more limited in that these can only be treated as full commands or “sentences,” as they occupy a distinct namespace accessed by the prefix @
.
- Express a phrase, or “replay a macro” —
@<name>
- Replay the last macro again —
@@
When you’re done recording, whatever you typed becomes a new command with the name that you gave it. Execute it by typing @q
(if you happened to name it q
— a convenient name I usually use), and if you want to repeat it, use @@
. These accept quantifiers, too. Even if you don’t use quantifiers often in general, with macros you will want to use them almost always, since repeating a complex action many times is precisely what macros are most commonly used for.
Try it! Say you have this text:
print hello
write hey
display bye
… and you want to change it so that on each line, the second word is a string in parentheses, with an exclamation point to boot: print("hello!")
. All you need to work with macros is q
, @
, and @@
. Go wild!
Finally, pause to reflect that macros give you a tremendous amount of flexibility. You don’t even need the Vim language anymore, if you can just record your actions and play them back at will. With a few basic commands and macros, you can do anything. But to forsake the Vim language at this stage would be to abandon the best thing about Vim macros — the fact that they are linguistic, denoting complex phrases in a language which express complex ideas, is what makes them as useful as they are. The better you speak Vim, the more expressive and precise your macros can be. 🦉