DEV Community

Igor Irianto
Igor Irianto

Posted on • Updated on

Automate typing with Vim macros

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
Enter fullscreen mode Exit fullscreen mode

You can then execute the macro with

@{your letter}
Enter fullscreen mode Exit fullscreen mode

For example, if you have strings

hello
Vim
macros
Enter fullscreen mode Exit fullscreen mode

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

qq0gU$q
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

We want to make

one: '1', 
two: '2',
three: '3',
// ... and so on
Enter fullscreen mode Exit fullscreen mode

Here is how we can do it:

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

qqea:<esc>wysiw"A,<esc>0jq
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Repeating macros

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

{number}@{your letter}
Enter fullscreen mode Exit fullscreen mode

So to execute our macro above earlier 99 times,

99@q
Enter fullscreen mode Exit fullscreen mode

Viewing macros

You can view existing macros with:

:registers
//or
:reg
Enter fullscreen mode Exit fullscreen mode

or individually with:

:registers {your letter}
// or
:reg {your letter}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

And we want to end up with:

{lib1: hello},
{lib2: hello},
{lib3: hello},
...
{libN: hello},
Enter fullscreen mode Exit fullscreen mode

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! 😁

Top comments (8)

Collapse
 
raguay profile image
Richard Guay • Edited

I would like to be able to insert a increasing number, so that:

#
#
#
Enter fullscreen mode Exit fullscreen mode

Becomes:

# 1
# 2
# 3
Enter fullscreen mode Exit fullscreen mode

I’ve only been able to do it in Sublime text with the Text Pastery plugin. Anyone know how to do it in vim?

Collapse
 
iggredible profile image
Igor Irianto

Vlastimil got it covered.

Alternatively, there are other ways I would do to approach it. One is:

:put=range(1,3) 

This allows you to insert column of numbers. First do that, THEN insert the #s after. You can do multiple insert with:

  1. C-v,
  2. Select down several times,
  3. insert with I
  4. <Esc>

Another alternative is to have #'s and 0's first:

# 0
# 0
# 0

Using C-v, highlight ALL 0's only. Then g C-a to increment them.

Hope it helps!

Collapse
 
raguay profile image
Richard Guay

Thanks. I’ve been looking for this type of stuff. I’m Using Onivim2 entirely except for this one item that I need fairly often. There are so many ways to skin a cat! I’ve been trying to get a multiple cursor solution, but I can’t get them to work. These work great.

Thread Thread
 
iggredible profile image
Igor Irianto

You're welcome. That's why I like modal editor like Vim. You can get the same thing done in many ways depending on the user.

Btw, on the side note, I never heard of Onivim2 before. onivim.io/ - looks interesting đŸ€“. I've never heard of it before until you mentioned it. How did you find out about it and what do you think about it?

Thread Thread
 
raguay profile image
Richard Guay

I was looking for a vim graphical program because my MacVim kept crashing. I came across Onivim, the original one, and loved it. But, it kept crashing also due to changes in neovim. I then started to just use neovim in the terminal all the time (that’s when I found kitty, a better terminal). But, I kept up with development of Onivim. When Onivim 2 started in public alpha, I jump right on it and have been loving it.

But, I’m an editor collector. I’ve used Emacs (in evil mode using the Doom config), Vi, Vim, Sublime Text, Atom (crashes a lot), Visual Code, skEdit, Syntra, CotEdit, Lite, and MacVim (the latest version isn’t crashing as much).

Collapse
 
vlasales profile image
Vlastimil Pospichal
:let i=1|g/^#/s/$/\=' '.i|let i=i+1
Collapse
 
raguay profile image
Richard Guay

Thanks. I’ve been looking for this type of stuff. I’m Using Onivim2 entirely except for this one item that I need fairly often.

Collapse
 
voyeg3r profile image
SĂ©rgio AraĂșjo • Edited

:let c=0 | g/#\zs/ let c+=1 | s//\=" " . c