2 Comments

How to Record and Replay Macros with Vim

Vim macros let us transform code like no other editor. Here’s how they work:

  1. Pick a register to record into. (A Vim register is like a little slot where the macro data will be stored. We usually want to record into one of the named a-z lowercase letter registers.)
  2. Begin recording with the q command.
  3. Edit however you want.
  4. End recording with the q command.
  5. Replay your macro wherever you want with the @ command.

A Simple Example

Macro moving block of three lines down three lines.
Macro moving block of three lines down three lines.

Let’s say we need a macro that takes three lines and moves them down three lines. We can accomplish this with the sequence d3djjp. (Cut 3 lines, move down two lines, then paste below the current line.) To record this as a macro into, say, register a, we’d type qad3djjpq. Then, wherever we wanted we could replay this sequence with @a.

Unleashing the Full Power of Vim Macros

The " quote in Vim is especially useful when working with macros. The " lets us specify what register we want to store text into when we’re yanking/deleting. This is needed, for instance, when we have multiple items to copy/paste at once.

Let’s create a macro to generate a Java getter method from a field declaration.

Macro generating a Java getter for a field.
Macro generating a Java getter for a field.

Here’s how we’ll do it. I’ll explain what each step does at a high level and then include the keys that accomplish it:

  1. Go to the beginning of the current line. (This is a good general practice that allows us to replay macros from anywhere on a line.) 0
  2. Advance to the second word of the line and yank the Java type into register ’t’. w"tyw
  3. Advance to the next word of the line and yank the field name into register ‘y’. w"yyw
  4. Begin writing the method signature. (^[ is how the escape character is displayed.) jopublic ^[
  5. Paste the Java type. "tp
  6. Paste the field name. "yp
  7. Go to the beginning of the field name, uppercase the first letter, and add ‘get’. b~higet^[
  8. Finish the rest of the method, including one more paste of the field name. (^M is a newline.) A() {^Mreturn this.^["ypA;^M}^M^[

When we put it all together we get:

qa0w"tyww"yywjopublic ^["tp"ypb~higet^[A() {^Mreturn this.^["ypA;^M}^M^[q

It looks pretty complicated, but we don’t usually see the contents of the register. Instead, we can focus on what our cursor is doing while we’re interacting with it.

What situations have Vim macros helped you out with?