Macro recording: Vim on steroids

Editors note: This is the seventh in a series of posts about vim (Vi Improved), Vi’s noble successor. If you’re new to vim then this post will be useless to you, so make sure you go and check out my very first post here.

If you thought vim was a fast, efficient text editor before you learned about macro’s, then you ain’t seen nothin’ yet…

When I started dabbling in code, it was to write R scripts for my honours project. I quickly became addicted to keyboard shortcuts. Naturally when I learned about vim, I was immediately intrigued.

All I was really looking for was something with better keyboard shortcuts than those that I knew of in the R script editor.

When I discovered vim, it solved this problem (understatement).

As my project progressed, I ended up having to wrangle ~40 independant data sets, which I was doing a number of identical analyses to. This meant that virtually all the code I was writing (whether in R or in bash, or some other command line tool like GCTA), I had to make 40 nearly identical copies of it, every time.

At first I was doing this the non-vim way

This is what led me to the discovery of one of vim’s most powerful editing features…

Macro recording…

It’s important to note that other text editors have this function also, but I didn’t know that when I learnt vim, so this just blew my mind. Moreover, given that what makes vim so powerful is that it is almost exclusively built around macros (keystrokes), then its relationship with macro’s, I suspect, is just always going to be more intimate than other text editors that are designed with a GUI in mind.

I’ve heard it said that vim can be thought of as ‘programming your code’. The best expression of this that I know of is macro recording.

Macro recording, if you’ve never heard of it, is basically copy/paste for your keystrokes, instead of for actual text on the screen.

By hitting a record button ‘qX’ where ‘X’ is any letter of the alphabet, vim will record all of the keystrokes you make in sequence until you stop recording by again pressing ‘q’, and then you can execute it as many times as you like.

Vim will automatically repeat those keystrokes verbatim. You can even specify how many times you would like vim to do this.

Once I learned how to do this… there was no going back.

If it’s not already obvious, by the end of this short post hopefully you’ll see how stupidly powerful this is when you need to anything in vim more than say, 2 times. When you need to do it 40 times, it’s virtually a necessity (for the sake of your sanity if nothing else).

Now, in hindsight probably some of the things I was doing for my project I could’ve written for loops and done other clever trickery to accomplish the tasks, but I was a total beginner back then and vim was already blowing my mind. Even so, for the things I was doing which were ‘repetitive’, really I only wanted to do them once, I can’t imagine for loops or functions would’ve been much quicker, I just needed to replicate the code.

Also, part of my motivation for this series is to interest other digital workers and content producers in using vim, not just programmers.

Soooo………

How it works

Macro recording is really really simple…

To start recording hit the record key:

q

followed by any letter, vim will start recording your keystrokes into a register (I know, I promise, we’re getting there). For now, just know that a register is like your computers ‘clipboard’, except that vim has more than one (it has lots), and they’re designated by the letters of the alphabet. To stop recording, hit ‘q’ again.

So, in order to begin a macro recording session, you need to initiate macro recording, and then designate which register you want to use.

For example, starting in normal mode I tend to use:

qa (start recording into register ‘a’)

because ‘a’ is under my pinky. Of course:

qq (start recording into register ‘q’)

also works fine.

From this moment, every keystroke you make, in any and all modes will be recorded in sequence and saved into register ‘a’ (or whatever letter you choose).

To execute the contents of register a, all I need to do is type (again from normal mode):

@a

or

X@a

where X is the number of times I want the operation performed.

For example, suppose I want to write a bullet point list in Markdown,

I can type this:

qaI- <cr><esc>q

Let’s go through that.

‘qa’ as I’ve just explained begins recording into register ‘a’

‘I’ enters insert mode

‘- ‘ is literally a dash and a space (because now we’re in insert mode)

‘<cr>’ if you remember is the notation for enter, so this will start a new line

‘<esc>’ exits insert mode back to normal mode

‘q’ stops recording.

What happens now is every time I execute the macro in register ‘a’, by pressing ‘@a’ it will create a new bullet point and a new line. If I execute it twice ‘2@a’, it will make two bullet point dashes then finish on the next line and so on.

Of course you can probably do this exact same thing easier by just copying the whole line and pasting as many times as you want. But this is only the simplest of examples.

The wonderful ‘.’ will repeat the last operation you performed, however performing numerous operations in succession, ‘.’ will only repeat the most recent. Macro recording will allow you to repeat an entire sequence of multiple operations.

Which means you can make a large number of identical changes in an instant.

Just to show you that this is no idle trick, let’s do some slightly more complicated examples.

Please note, in the following examples, numerous times I reference ‘0’. In every single instance I’m referring to the number zero, not uppercase ‘o’.

Some slightly more complicated examples

Example 1 – Using macros with increasing numbers

The next evolution from creating unordered lists, is creating ordered lists. Macro’s shine at this.

Say I’m doing some writing in Markdown and I want to create a numbered list.

Well, you could type out each number as you make that item on the list, or…

You can just write out your list:

This is the first item on this list

This is the second item on this list

This is the third item on this list

This is the fourth item on this list

This is the fifth item on this list

This is the sixth item on this list

Then, just input the first number of the list like so:

1. This is the first item on this list

This is the second item on this list

This is the third item on this list

This is the fourth item on this list

This is the fifth item on this list

This is the sixth item on this list

Now, we can start recording with ‘qa’. From here you can jump to the beginning of the line, yank the number, paste it on the line below, then use a clever trick to increment the number, which I’ll show you shortly, then stop the recording. The exact key sequence will look like this:

0qayWj0P<C-a>0q

Don’t freak out.

Lets break it down:

0qa – move cursor the very beginning of the line and start recording into register ‘a’

yW – yank all the text from the cursor to the beginning of the next block of text following whitespace

j0 – move down to the very beginning of the next line (you should already be at the beginning of the line, but I’m a bit paranoid, so I hit ‘0’ again anyway just for good measure

P – paste the yanked text behind the cursor, this pastes the number at the beginning of the line

<C-a> – this is the tricky command. The ‘C’ stands for <ctrl>  and the ‘a’ stands for the letter a. What this is saying is, press and hold <ctrl>, and press ‘a’. Control + a will increase the value of the integer under the cursor by one. so 1 becomes 2, 2 becomes 3 and so on. (FYI <C-x> will decrease the integer by one also!)

0q – jump back to the very beginning of the line (again, you should already be there, but you can never be too careful when recording macros) and stop recording.

Your list should now look like this:

1. This is the first item on this list

2. This is the second item on this list

This is the third item on this list

This is the fourth item on this list

This is the fifth item on this list

This is the sixth item on this list

Now, with your cursor sitting on the ‘2’. Press

4@a

If you did everything correctly your list should now look like this:

1. This is the first item on this list

2. This is the second item on this list

3. This is the third item on this list

4. This is the fourth item on this list

5. This is the fifth item on this list

6. This is the sixth item on this list

Now you might think it’d be just as easy to type the numbers out as you do each line, but this is only an illustrative example. Plus it’s way cooler and more fun to do a macro, but whatever.

Example 2 – using macros across modes

Now say you want to write the same list in html.

The benefit of a macro should be even more obvious in this example.

This is the first item on this list

This is the second item on this list

This is the third item on this list

This is the fourth item on this list

This is the fifth item on this list

This is the sixth item on this list

With this we can jump right into the macro. With your cursor anywhere on the first line you can start recording, then use ‘I’ to enter insert mode in front of the first character on the line, enter your list tag, then escape back to normal mode, then hit ‘A’ to enter insert mode after the last character on your line, enter your end list tag, then escape back to normal mode and jump down to the next line (if you’re totally paranoid like me you can 0 back to the start of the line again), then stop recording.

The exact key sequence for this macro will look like this:

qaI<li><esc>A</li><esc>j0q

Now with your cursor on line two press:

5@a

and now your list should look like this:

<li>This is the first item on this list</li>

<li>This is the second item on this list</li>

<li>This is the third item on this list</li>

<li>This is the fourth item on this list</li>

<li>This is the fifth item on this list</li>

<li>This is the sixth item on this list</li>

Without a macro, you would have to do your first tag, then you could ‘j.’ for each line, then you could enter your end tag on the bottom line, then ‘k.’ back up again. Compared to any other text editor, this is still heaps quicker, but the macro makes it almost no effort at all.

As you begin to get better at using macro’s you’ll begin to find all kinds of incredible, clever ways to do things, so get to it!


Thanks so much for reading. If you liked this post make sure you subscribe and get the rest of my posts as they come out.

We’re beginning to reach the limits of information you need to know about vim to get yourself in and comfortable, but I’ve still got a couple more things I want to cover, including plugins, registers and where to go to get more good reliable information about vim.

If you guys really really love these posts and enjoy my obnoxious and verbose writing style, then leave me a comment here or come find me on twitter, Reddit, linked in or Tumblr and tell me that you want more, more, MORE posts about vim!!

If I do get like, a ton, of people telling me that I just have to keep going, then I might start writing more vim posts. Otherwise I will assume my bare bones introductory series is satisfactory, and will endeavour to make it into some sort of downloadable… thing, and continue to write posts relevant to my PhD topic.

For more information on why I started this blog make sure you check out my about page and my sticky post.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s