Home > Point2 - Technical > Vim Tip – Registers and Macros

Vim Tip – Registers and Macros

June 19, 2009

Let’s say you’re a beginning vim user. You know how to yank, put, substitute and change. You know how to do forward searches within a line or do searches ’til’ a certain character; you can use /, ?, *, # effectively. You can combine your searches with commands to work some serious magic. You’ve seen the light. Vim is your One True Editor.

So what’s next? If you’ve mastered the basics, registers and macros are a good place to go turn pro. I’ll briefly explain both concepts, and then use an example to show how these features complement each other.

Registers

A register is like a variable in a typical programming language. It’s a location in memory where you can store something. We’ll look at two usages for registers: storing text, and storing macros.

Normally when you yank a line with yy, it’s contents get saved into the default, unnamed register, called “” (quote-quote). If you want to yank something into another named register, say register a, you have to prefix your yank with “{register}. The same goes for puts.

So for example…

yy    yank the current line into the unnamed register
"ayy    yank the current line into register a
"ap     put the contents of register a

Simple right? At first it might seem that this is only marginally useful, but registers can greatly simplify some macros. So we’ll talk about that next.

Macros

The q{register} command starts recording a macro. While you’re recording a macro, press q again to signal that you’re finished.

I like to use the q, w, e, and r registers for macros, simply because they’re easiest to reach. So for example, to start recording a macro, I’ll press qw, record my actions, and press q to signal the end of the macro.

The @{register} command executes a macro. So I can execute my new macro with @w. Usually once I know that it works, I’ll also have to run it many times with something like 100@w.

Tying it together

This came up a few weeks ago when I was generating some characterization tests. I had written a quick script to generate some test data in CSV; in reality it was a bit more involved than what follows, but this gets the point accross:

Input, Output
34523451, true
65434092, true
45810353, false
(~1000 more of these)

I had also written a single test at the bottom of the file, and I wanted a thousand more that all followed the template.


[Test]
public void Test() {
    Assert.AreEqual(IsNumberValid(INPUT), OUTPUT);
}

So I used a vim macro — the vim keystrokes are in brackets () after each step:

  1. Cut the test template into register a (/\[Test<Enter>”a4dd)
  2. Move to the beginning of the file, start the macro (ggqq)
  3. Copy 34523451 into register b (“byw)
  4. Copy true into register c (f l”cyw)
  5. Delete the current line (dd)
  6. Put a copy of the test template at the end of the file (G”ap)
  7. Replace INPUT with the contents of register b (/INPUT, dw, “bP)
  8. Replace OUTPUT with the contents of register c (/OUTPUT, dw, “cP)
  9. Move the cursor back to the beginning of the file (gg)
  10. End the macro (q)
  11. Execute the macro 1000 times (1000@q)

Using the above, I was able to generate a ton of code in a minute or so. If I had tried to cobble together a script to do the same it would have taken at least several times as long. I use vim macros almost daily. I don’t often have to combine them with registers, but I’ve found it to be an invaluable technique in certain situations.

By Kevin Baribeau

Advertisements
  1. Steve
    June 20, 2009 at 11:05 PM

    Great post Kevin. Very informative. Thanks a lot.

    I think there might be a slight error with step 3. Because the first line of the file is “Input, Output” I think you first need to move down one line. For me step three was:

    3. Copy 34523451 into register b (j”byw)

    That’s what worked for me anyway 🙂

  1. No trackbacks yet.
Comments are closed.
%d bloggers like this: