Vim's macro

Vim's macros are very efficient, elegant and worth checking out. If you already like the dot (.) command, you will love macros. Vim's macros allow you to repeat a recording of a sequence of command.

For the following examples, I will use this content, the goal is to remove the spaces and the trailing commas.

a, 2,
b, 3,
c, 4,
d, 5,
e, 6,

Using visual block mode

Although this article is about using macros, I will start with the way I was doing it before I knew about macro. As you'll see later, macros are way more elegant !

This will be done using the visual block mode of vim, selecting a full column and then applying a command to the entire column.

  • Select the spaces and delete them

    f<space><CTRL>v99jx
    
  • Go to the end of the line, select the commas and delete them

    $<CTRL>v99jx
    

Here's a description of the different steps above:

  • f<space> goes to the first space
  • <CTRL>v enters visual block mode
  • 99j applies 99 times j in order to select the entire column in the file
  • x deletes everything that's being selected
  • $ goes to the end of the line
  • ...

This is a little screencast of this execution:

vim visual column

Using a macro I

With a macro, you can record a single execution on the first line and then execute it on all the subsequent lines. Using macro in vim is quite easy: the recording is started with q<register> and ended it with q. It is then applied using @<register>.

Try it:

  • start recording (here in register a): qa
  • everything is now being recorded and saved in register a
  • find the next space: f<space>
  • delete it: x
  • go to the end of line and delete the comma: $x
  • stop recording: q

You can visualize the list of commands saved in the a register using :reg a. And then apply that to the rest of the lines:

  • select the second line up to the end of file: :2VG
  • and execute the macro: :norm @a

That's it !

vim macro example 1

The normal command (here I used the shortcut norm) is used to execute a set of vim commands as if you were in normal mode (see :help normal for more info).

Using macro II

In this second example, the goal is to change the case of the first character and then increment the number by one using macro:

  • start by going to the beginning of the file: gg
  • record the macro in register m: qm
  • toggling case is done with tilde: ~
  • then go until the next comma: t,
  • increment the number under the cursor with: <CTRL>a
  • and go to the next line: +
  • finally save the macro: q

You can then apply that macro using @m multiple time (since the + was used, the macro will automatically jump on the next line). A good time saver is @@ which will repeat the last macro. Another way of repeating a macro is by prepending the command with a count as for example 99@m.

Using macro III

This is another nice example of the power of vim's macro.

Our example file:

a,"this is a"
b,"this is b"
c,"this is c"

The goal is to replace what is inside the quotes with is no more and add the first char of the line at the beginning of that text such that a,"this is a" becomes "a,"a is no more" and apply that to all subsequent lines.

Let's get started on the first line:

  • start recording in buffer q: qq
  • go to the first space (any place inside the quotes will do): f<space>
  • and then edit the whole content inside the quotes: ci"
  • add the new text: <space>is no more
  • escape editing mode
  • go the the beginning of the line: 0
  • copy the char under the cursor: yl
  • go to the first quote: f"
  • paste the char: p
  • stop the recording: q

And then apply it to all lines:

  • go to the second line and select all lines up to the end of the file: :2VG
  • apply the macro to these lines: :norm @q

Here's a little screencast that demonstrates this execution.

vim macro example 2

One more thing: you can append more command to a macro by restarting the macro with the capital letter of the register where you saved your commands. For example qA ... q for register a.

I hope next time you'll have to apply the same pattern to a content, you will try to use macros !