Do you want to know more about how to use macros in Vim? In this talk, learn tips and tricks for mastering macros in Vim with an example project.

This talk was presented by Camilo Payan at VimConf 2021 on October 29, 2021.

(instrumental music)
Hi, my name is Camilo Payan and thank you for coming to this talk, Mastering The Macro Machine. You can find me online at, and let's get right into it. I work for a company called Test Double, where we work to make software better, and as an aside, we're hiring. As part of my work as a consultant at Test Double, I maintain a library that we have called Standard Rb, which helps Ruby developers get started with a baseline for the popular Ruby linting tool, RuboCop.
So for this talk, I went ahead and made myself some silly little tasks. We're gonna disable every cop and we're going to create a table of contents for the README file. And I want to do this all in Vim with the power of movements and macros. So what do I mean by movements? Movements are the building blocks of text editing in Vim. They are commands in normal mode that will move you somewhere else. The most basic, which you probably already know, are `h`, `j`, `k` and `l`, and what's really great is you can combine those movements by prefixing them with them with a number to have it go more than once.
So let's go ahead and demo that by opening up our base config file and you know `j` goes down, `k` goes up. If we go over here, `l` goes to the right and `h` goes to the left. Now, if we do five `j`, it takes us down five lines. And what do we mean by macros? So a macro is basically a recording of the keystrokes. You start one by using `q` and the letter that you wanna name your macro. You can also use numbers, but I recommend you use letters for a reason that will become more obvious later. Then you do all your keystrokes and Vim is recording them, and then you can finish your recording with `q`. Then you can repeat your macro with at and the letter that you gave your macro.
So let's get to work on disabling every cop in this file, and if we take a look at the config, all these cops are enabled or disabled using this kind of line here where it says enabled true or enabled false.
So let's start our macro. I wanna call it `a`, and first things first, we're going to search for the word enabled. I'm going to hit `l` a bunch of times to get to where we wanna be, and then we'll change the rest, we'll just put an `f` for now. And then once we're back in normal mode we hit `q` to finish recording. So now if I go down to line 17 and I run `@a`, it runs it again. So, this is the general idea of macros. I don't have to redo all of the keystrokes by hand over and over again, saves you a bunch of time.
Now, F is for respect, but we actually want the whole word false and we're gonna do that by appending to the end of the macro. So if I made my macro `qA`, so I'm going ahead and at the same spot where my macro ends use `qA`, and you can see announced as recording at `A`, and let's append to the end of the line. And finish recording our macro with `q`, and now, even if I change this to something really cool, it works. I didn't have to re-record
Now the cool part about this is because we know where this is, we can start manipulating our macro by taking it out of the
`f` forward searches on a letter. So if I do `f` to the colon, that goes to the end. Let's do `fe` and then
You can use zero to get to the 0th character, which will always be the very first character in the line, or you can use caret
Another thing you can do is suffix your macros. So you wanna suffix your macro in order to set up the next one of the macro, and then you can repeat it like we did with `5j` and really unlock the repetition of your macro.
Now, these are different movements that you could be using. So plus takes you to the beginning of the next line. So here it goes to the dash, over there it went to the capital E and it's basically the same as using `j` and then the caret key, but it's only one key. So that's nice. Another thing that you could use for suffixing is `n` which takes you to the next instance of your search, and that could be useful here, because actually we are searching for the word enabled. And another thing that you could do is use `*`, which takes you to the next instance of the word under your cursor, which is really useful, depending on what you're doing, but it's worth remembering that it does replace your search.
So now if you hit `n` it's gonna be looking for bundler and not enabled. For the purposes of this macro, I'm gonna go ahead and add a plus, let's go ahead and yank it back into our `a` register, which we won't actually be able to see that. And now I can go ahead and let's go to number 10, hit `@a` and it works, and it takes it to the next line, which means I could do
All right, so the next task that I gave myself was creating a table of contents for READMEs. So when a README file gets pretty long for an open-source project like this, I really like for there to be some kind of table of contents, that way I can go straight to information that I want without having to like kind of read through the whole file. And since this is a Markdown file, we can kind of guess that every heading is gonna start with a hash.
There's actually a Ruby comment here, but it looks like we're starting with two hashes anyway. So that's how we're gonna
Let's go forward to word and into our `s` register, I'm gonna go ahead and yank all of this. Now let's go to the next line and I want to start thinking ahead and set up the next run of this by creating a mark right here, we're gonna call it `x`. Now let's jump back to where
Now I wanna create a new mark here. That's gonna be our new `z` mark, and let's go back to our `x` mark, and that's it, that's our macro. Now, I already remember that there was actually a problem in my macro. I'm not really sure where that was, but let's see if it works. Now, the next heading, I think is usage. So let's see if that works. See, I have an error in the middle of my macro, so this is where I bring that stuff together. This looks good. This is, all of that must go. Cool, now we have a macro that works. Now, if you run it again, we should be in usage, let's take a look for our table of contents. Yeah, we have usage going up here and now if you run it, you
I don't actually know how many headers there are here. Let's try another five. I think that takes us, let's do another one, and now we have a problem. We went to the beginning of the document again. So let's take a look at table of contents. We have everything that we expect, but now we have the
Now, recursive macros will go ahead and run the macro inside your macro so then it just keeps running. But in this case, since we're relying on a search, Vim will go ahead and wrap to the beginning of the document if you are still searching at that point, and you're at the end of the document, but we wanna get rid of that because a recursive macro won't stop unless there's an error, which is actually why I
We're gonna use this setting, `nowrapscan`. So, if you hit `nowrapscan` what happens is even if you're at the end of the document and we keep searching, so we wanna search for table of contents, it's not gonna keep going past the end of the document. So that will be useful in this case, because now if I finished my macro by hitting `@a`, and yanked that back into my register and let it run, it's just gonna run itself over and over but when it gets to the end of the document, it's going to stop. So code of conduct is the last one that we are looking at. Let's take a look at a table of contents. Yeah, it goes all the way from the rules to code of conduct, works great, mission accomplished.
Now, one more thing that we could take a look at is this setting here, `lazyredraw`. It's really fun and it's cool for demos to watch your macro run, but with `lazyredraw`, you can skip all that and you know, not just sit here watching your computer work, it's going to wait until all the commands are finished and then that's when it's going to actually redraw your file. So here we go. It can be useful but I kind of like watching macros.
Anyways, thank you so much for coming to this talk. I hope you enjoy the rest of the conference. You can find me online at; I'm Cam on the Discord and also a reminder, Test Double is hiring, and you know, if you'd like to come work, just go ahead and ask any

Camilo Payan

Hash An icon of a hash sign Code Name
Agent 0081
Location An icon of a map marker Location
South Florida