Chapter 19.Table of ContentsCheatsheet

Reusable Editing With Macros

Vim loves saving you time and hassle, and offers you lots of ways in which you can repeat commands:

  • The . command lets you repeat the last change.
  • The ; and , commands let you repeat the last character search forwards and backwards respectively.
  • n and N let you repeat the last search also forwards and backwards.
  • / and ? also let you repeat the last search forwards or backwards.
  • :@ and @@ let you repeat Ex commands.

Vim macros take this power of repetition to the next level by allowing you to record a collection of commands as you type them, and then replay them at will. As such, macros become reusable editing actions that can save you a lot of time.

Creating a New Vim Macro

You create a new macro by following this process:

  1. Type q{register} to start recording a macro (e.g. qq will start recording a macro to register q) inside a register.
  2. Perform the different actions you want to include in the macro.
  3. When you’re done, type q to end the recording.

From then on, you can replay the macro whenever you want:

  • Type @{register} (e.g. @q) to execute the macro that lives in a given register.

Once you’ve run a macro once, you can repeat the last macro by typing @@. This follows the same spirit of the other repeater commands in Vim.

Macros in Action

Let’s use an example to illustrate the use of macros in Vim. Imagine that you have a list of some common items that you could find in any 8-bit fantasy RPG shop sold by an extremely boring NPC. They are separated by commas like this:

rusty sword,obsidian dagger,silver poniard,broadsword

And now imagine that you want to grab that list and turn that into HTML. Web 1.0 here we come. The resulting HTML would look like this:

<ul>
  <li>rusty sword</li>
  <li>obsidian sword</li>
  <li>silver poniard</li>
  <li>broadsword poniard</li>
</ul>

A possible approach to solve this problem is to create a macro that encapsulates the process of grabbing an item from a list and putting inside a li element.

So, starting with the cursor in the first letter of the list:

v
rusty sword,obsidian dagger,silver poniard,broadsword

we can do as follows:

  1. Start by recording the macro in the q register with qq.
  2. Then use f, to find the first ,.
  3. Type cw<Enter><ESC>k to remove the comma and move the list but for the first item to the next line then back up:
   --- cursor is here
  /
 /
|
v
rusty sword
obsidian dagger,silver poniard,broadsword
  1. Now I<li><ESC> to insert the opening tag.
  2. Then A</li><ESC> to insert the closing tag.
  3. Move to the beginning of the line below j0 .
  4. Finish recording the macro by typing q:
<li>rusty sword</li>
obsidian dagger,silver poniard,broadsword
^
 \
  \
   ----- cursor is here

Now just type @q to replay the macro and you’ll get this:

<li>rusty sword</li>
<li>obsidian dagger</li>
silver poniard,broadsword

Now type @@ to repeat the last macro:

<li>rusty sword</li>
<li>obsidian dagger</li>
<li>silver poniard</li>
broadsword

If you try to use our macro again, you’ll be surprised to find that nothing happens. Why? Because Vim can’t find any comma, the macro stops executing. We can fix this by adding a comma at the end before we start processing the line of items:

rusty sword,obsidian dagger,silver poniard,broadsword,

And now if we combine the power of counters with macros we can process the whole line of items at once. Type 4@q:

<li>rusty sword</li>
<li>obsidian dagger</li>
<li>silver poniard</li>
<li>broadsword</li>

You’ve completed your task (victory dance).

I hope this example was illustrative of the power of macros and it serves as inspiration in you future coding sessions. The greatest thing about macros is that you can use the same techniques (motions, operators, counts, etc) you normally use to write code and package them so that they can be reused later.


Jaime González García

Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.Jaime González García