Vim macros

I’m a huge fan of Vim. I should say there are a lot of things that are not modern there. One such thing is using Ctrl instead of Alt – which, on modern keyboards, is much more suitable for usage – and, while we are still at that – Alt doesn’t actually work in terminal. You can get away with it using Esc timed mappings, but that’s a hack that has its own issues.

Aside from that, Vim has a lot of very neat features. One of them is the ability to create macros insanely fast. To create a macro, you need to be in the normal mode, i.e. nothing in the status line on the bottom. If you are not familiar with the modes, take a look here. To start, press ‘q’ and any letter – let’s say we use ‘q’, so press ‘qq’. This will start recording the macro with the name equal to the second letter you pressed, in this case ‘q’. On the bottom you will see ‘recording’. Now, you need to do the actions you want macro to contain, in the usual fashion you do the editing. When you are done, press ‘q’ again to finish recording the macro (the ‘recording’ will disappear from the status line, i.e. Vim will go to normal mode).

How can this be useful? Here’s a quick example. Say you have a site with the following URLs active:

www.example.com/blog/post1
www.example.com/blog/post2
www.example.com/blog/post3/comments
www.example.com/wiki/page1
www.example.com/wiki/page2/attachments
www.example.com/wiki/page3
www.example.com/wiki/page4/subpage41
www.example.com/misc/about

Now you decided that you want to make subdomains instead of first-level links. So the first one:

www.example.com/blog/post1

would become:

blog.example.com/post1

Let’s see how you can transform this very quickly using macros. First, position your cursor – I’ll use ‘|’ to mark the cursor position – at the beginning of the first line:

|www.example.com/blog/post1
www.example.com/blog/post2
www.example.com/blog/post3/comments
www.example.com/wiki/page1
www.example.com/wiki/page2/attachments
www.example.com/wiki/page3
www.example.com/wiki/page4/subpage41
www.example.com/misc/about

Press ‘qq’ to start recording macro ‘q’. In this case, the macro could be made to work on one line only – repeating the macro for each line will give the desired outcome. What should macro do on each line? Here’s the summary for the first line:

www.example.com/blog/post1

Note for the below – when I write press ‘dt.’, that means pressing d, then t, then . – i.e., remove the quotes. The steps are: * Delete ‘www’ at the beginning – press ‘dt.’ to delete all up to the first dot

|.example.com/blog/post1

  • Go to the word after the first slash – in this case it’s ‘blog’ – by pressing ‘f/l’ ** ‘f/’ is doing ‘find /’, i.e. positions the cursor to the next slash after the current cursor position ** ‘l’ is moving the cursor one place to the right

.example.com/|blog/post1

  • Yank that word into some register as we will need it later – press ‘”ayw’ which literally means “into register ‘a’ yank next word” ** If you are unfamiliar with registers, take a look here
  • Delete everything up to and including the following slash – in this case ‘blog/’ – by pressing ‘df/’ which means “delete everything till and including next slash”

.example.com/|post1

  • Paste the word at the front – press ‘0″ap’ ** ‘0’ goes to the beginning of the current line ** ‘”aP” literally means “from register ‘a’ paste before current cursor position”

blog|.example.com/post1

  • Prepare for the next macro iteration – go to the beginning of the next line by pressing ‘0j’ ** ‘0’ goes to the beginning of the current line ** ‘j’ goes to the next line

  • Press ‘q’ to stop recording the macro – you are done!

This looks like a lot of steps, but as soon as you do a few of these it looks like a breeze.

Let’s use the macro now. Note that recording the macro already performed the necessary operations on the first line and positioned the cursor on the start of the second line, so the text now looks like:

blog.example.com/post1
|www.example.com/blog/post2
www.example.com/blog/post3/comments
www.example.com/wiki/page1
www.example.com/wiki/page2/attachments
www.example.com/wiki/page3
www.example.com/wiki/page4/subpage41
www.example.com/misc/about

You need to perform it only on the outstanding lines. To run the macro, you use ‘@q’ which runs macro named ‘q’. For all subsequent runs, you can use a shortcut ‘@@’ which means run the last macro run. Try this now – press ‘@q’ to execute it on the second line and you will get:

blog.example.com/post1
blog.example.com/post2
|www.example.com/blog/post3/comments
www.example.com/wiki/page1
www.example.com/wiki/page2/attachments
www.example.com/wiki/page3
www.example.com/wiki/page4/subpage41
www.example.com/misc/about

Now, lets to the other lines at once – there are 6 lines left, so press ‘6@@’ to repeat the last macro used – our macro ‘q’ – 6 times. You’ll get the final desired result:

blog.example.com/post1
blog.example.com/post2
blog.example.com/post3/comments
wiki.example.com/page1
wiki.example.com/page2/attachments
wiki.example.com/page3
wiki.example.com/page4/subpage41
misc.example.com/about

The above example is just a scratch – look at this YouTube video for a very short, but very demonstrative display of how much Vim macros can be useful.