Automate typing with Vim macros

December 28, 2019

If you're interested to learn more Vim, follow @learnvim for tips/tricks!

Vim macro is a powerful feature that allows you to record sequence of keys on the fly. Knowing how to use macros effectively allows you to automate typing, saving you time in the long run (plus it looks cool 😎).

This is an intro to Vim macros. I will cover the very basic to more advanced use of vim macros. Don't feel like you have to master every single techniques listed. Take your time practicing them. After reading this article, I hope you can get started recording your own macros!

Intro

Basic syntax of Vim macros:

q{your letter}{series of commands}q

You can then execute the macro with

@{your letter}

For example, if you have strings

hello
Vim
macros

And you want to capitalize each strings. While you are on hello's h, and type:

qq0gU$q

You have just recorded your first macro!

Btw, you technically capitalize everything by doing gUg, I am doing it to show how macro works.

Now if you go to next line (to "Vim" line) and run @q, watch it capitalize "Vim" automatically. You can repeat @q on the next line.

Let me break it down the key sequences:

  • qq -> start recording macro (:h q for more information) at q (or any letter you want) register
  • 0 -> go to beginning of line
  • gU -> operator to capitalize
  • $ -> motion to go to the end of the line. gU$ means capitalize to the end of line
  • q -> end recording macro

PROTIP: use mnemonics to help remember macros if you have multiple macros. If you have a macro that focuses on modifying function use f register (qf), n (qn) for macros dealing with numbers, etc. The point is, name it with whatever FIRST THING that came up to your mind when you think of that macro. Also personally, my default macro letter is q, because qq doesn't require much brain power to use.

Basic macros

Let's do more examples!

one 1
two 2
three 3
// more

We want to make

one: '1', 
two: '2',
three: '3',
// ... and so on

Here is how we can do it:

Cursor on one's "o", record the following macros:

qqea:<esc>wysiw"A,<esc>0jq

Let's break it down:

  • qq -> record macro on q register
  • ea:<esc> -> go to end of word (e), insert mode after cursor (a), inserts :, go back to normal mode (<esc>)
  • w -> jump one word
  • ysiw" -> Using vim-surround, add " around a word (ysiw)
  • A,<esc> -> insert mode at the end of line (A), insert ,, back to normal mode
  • 0j -> back to start of line (0), go down one row (j)
  • q -> end record

To execute the macro, just run

@q

Repeating macros

Macros are repeatable, here's how you can do it:

{number}@{your letter}

So to execute our macro above earlier 99 times,

99@q

Viewing macros

You can view existing macros with:

:registers
//or
:reg

or individually with:

:registers {your letter}
// or
:reg {your letter}

Macros are saved inside Vim registers - the same register where you copy paste vim (if you need a refresher on Vim register, you can check this out!)

PROTIP2: to paste register q's value, we can do it by: first, go to insert mode then, press <Ctrl-r><Ctrl-r>q

Edit existing macros

So you finished recording a macro and realized you made a mistake, you can edit it instead of re-recording it.

Let's say you have a macro that inserts a } at the end of line:

qqA}<esc>q

Later you realize you need to add ; after }. Instead of rerecording qqA};<esc>q, let's learn how to edit it:

  1. "qp
  2. adds ; after }
  3. still on that line: first go to the beginning of line (0), then yank the rest of line to q register ("qY)
  4. Now when you run @q, it will append };.

Another way to edit your macros is from Command mode (:)

  1. :let @{register}='
  2. get the content of that register <Ctrl-r><Ctrl-r>{register}, this will paste the content of that register
  3. edit that register
  4. Close the quote: ' 5 <Enter>

I find this method useful for editing short macros 👍.

Recursive macros

You can run a macro recursively to execute it multiple times.

Suppose we have:

lib1
lib2
...
libN

And we want to end up with:

{lib1: hello},
{lib2: hello},
{lib3: hello},
...
{libN: hello},

We can do it with regular macros and execute it N times (N@q), but why do that if we can do it in just a single execution with recursive macro?

Here's how you can do it. Cursor on lib1's l:

  • qqq - clear up q register
  • qq ysiw{ ea: <SPACE> hello <ESC> A, <ESC> 0 j @q q (I space them into groups for readability)
  • @q

Let me break down the second line:

  • qq -> record macro on q register
  • ysiw{ -> vim-surround: add around a word
  • ea:<SPACE>hello<ESC> -> go to end of word, insert mode, add : hello, then back to normal mode
  • A, -> go to end of line, add ,
  • 0j -> go to beginning of line, go down
  • @q -> execute q macro
  • q -> end recording

Now the recursion occurs when we execute q macro @q WHILE we are recording in q register. It is important to clear up q register before recording it (qqq).

We've reached the end. It takes a lot of practice to get comfortable with Vim macros. My two cents: don't be discouraged, you can do this. I also struggled tremendously when starting out. Detect any opportunity to use macros and use them; the more you do it, the comfortable and faster it gets.

That's all for now. Thank you for reading this far, I really appreciate it. Until next time! 😁