~ 2 minute
If for some crazy reason you’re not already a user of Vim, shutdown your computer and go think about your life choices.
Joking aside, Vim is really a great editor. And if you didn’t know – Vim supports macros.
Basics of macros in Vim
Macros represent a simple concept which can be described as “record the sequence of my actions, save them, and anytime I need them again, execute them.”
This is probably the most underused Vim feature which can improve your productivity dramatically. You can do all sorts of amazing stuff with your code using macros.
Incredibly powerful. Here’s a simple example:
What’s happening here:
qa
– start recording macro in registera
i<Tab>'
– enter Insert mode, insert Tab and ‘Esc
– get back to Normal mode (so I can run next command)A
– Append command, which places cursor at the end of the current line, in Insert mode',
– Insert',
Esc
– get back to Normal mode againj
– Go down one line^
– Go to the start of the current lineq
– Stop recording the macro
Then, using command @a
I run the macro on the current line. After that, I can just hit @@
to run the macro I previously run.
Recursive macros
Using macros can be even more effective with recursion. Recursive macros are especially useful when you need to act on many lines in a file.
In order to record a recursive macro, you need to start with an empty register. You can make the register a
empty by hitting qaq
.
Now, let’s see recursive macro in action, with a slightly different example:
Let’s see what’s going on here:
qa
followed by Tab and'
followed byEsc
– same as in first examplef:
– find the first occurrence of:
and place cursor on itC
– command to delete everything from cursor to the end of the line, and enter Insert mode',
followed byEsc
,j
and^
– same as in the first example: insert',
get to Normal mode, move one line below and jump to beginning@a
– this is the key step: while recording a macro in registera
, we call it inside itself!q
– stop recording the macro@a
– now we run the recursive macro – and there you go – magic! :)
There’s so much more you can do with macros in Vim!
My colleagues sometimes stare at my screen and wonder wtf is going on, when my hands are even not on the keyboard – and my code is being edited by a macro :D
You can master this magic too!
Get Macros chapter (plus three other!) from my book Mastering Vim Quickly for free.
If you liked the post, we should get connected - follow me on Twitter
Thanks! I use macros a lot and never knew you could do that. But how does that macro know when to stop, in your example?
There’s no another `:` to jump to on the next line (after the last one edited by macro). That’s exactly why I used f: in this example.
What’s the stop condition? Why doesn’t it keep going?
It stops because there’s no another `:` to jump to on the next line. That’s exactly why I used f: in this example.
Cool! What I didn’t understand is how vim knows when to stop running that macro. I mean, in the example there is more lines below the list of IPs but they keep untouched.
It stops because there’s no another `:` to jump to on the next line. That’s exactly why I used f: in this example.
I believe you are missing an escape command before the j in both of your examples.
Thanks, fixed!
Nice trick.
Why not use @a to run the macro exactly the number of times your need it without leaving stray characters when done?
Or start the macro with a more precise find?
Those are the valid available options. Sometimes, recursive macro is the best way to go, and many people don’t know about it. So that’s why this post ;)
Some of us are lazy and don’t want to count the (potentially) tens or hundreds of lines needed when we want to run a macro ;)
Nice!
Another neat trick is to use your first macro, then visually select the rows that you would like to change (e.g. Vap or similar) then type :normal @a to run the macro on all lines in your selection.
That’s what I wanted to add too. :normal FTW!
I’ve been learning Vim for less than a month, and I am trying to gather all the useful information I can get, and this was great!
I’m planning to make it my main text editor and It really seems like anything can be done with it.
Thanks!
Nice tutorial. I find the magic of recursive macros to be super powerful–especially when you have a very large (but not necessarily known) number of changes that need to be made.
Based on your example of framing the IP address in single quotes, you may want to check out Tim Pope’s vim-surround plugin, which simplifies the process of framing a block of text with single/double quotes, parens, brackets, curly braces, & even HTML/XML tags. It’s one of those plugins (although I’m generally not a fan of vim plugins) that’s so useful & intuitive that I can’t believe that it hasn’t been rolled into the Vim codebase itself.
I second that. tpope’s plugins are superb, especially this one.
Nice one! I don’t use recursive macros as much as I should. This helps. Although, I should mention that I wish posts like this point it out more often that the ‘a’ in ‘qa’ is just a register. In fact I prefer qq instead of qa since it is faster and I have a mapping to @q. For example, your step for starting with an empty register would just be qqq
Pingback: The Energy of Recursive Macros in Vim | Your Cheer
Pingback: The Power of Recursive Macros in Vim – Full-Stack Feed