Cheap Shared Hosting

Wednesday, March 5, 2008

Another VI tip - using macros, an example

God I love VI. Well, actually, vim but whatever.

Here's another reason why. Suppose you need to perform some repetitive task over and over, such as updating the copyright date in the footer of a static website. (Yes, yes I know you could do a javascript thing or whatever, just bear with me.)

Of course you could just search and replace in some text editor, changing "2007" to "2008" (if you're stupid) - and you'll end up with a bunch of incorrect dates being changed, most likely. What you need to do is only change that date at the bottom. And suppose that because of the formatting, you can't use the "Copy" part of the string in a search replace - perhaps some of the pages use "©", some spell out "Copyright" etc.

This is where vi macros come in handy. A macro in vi is exactly what you expect, it records your actions and allows you to play them back.

To start recording, press q followed by a character to use to "store" the macro. Let's say since it's the copyright date you're updating, you enter qd to start recording into the "d" buffer.

Then perform your actions. Since you want to get the last "2007" in the document, do GG to jump to the bottom of the document, then "?2007" to search backwards for the first 2007. Move your cursor and make the change. Then save the file with :w, and end the macro recording by hitting q again - you now have a macro, and can trigger those commands by hitting @d !

You could even change that last step to the :wn to have vi move to the next file in the queue - but I like to give myself a chance to see what changed before going to the next file - this way you can hit u if you need to undo what you just did.

You can use macros to automate just about anything, and when combined with regular expressions for changes or getting around the file, you have one heck of a powerful tool for editing!

6 comments:

Adrian said...

Then save the file with :w - you now have a macro, and can trigger those commands by hitting @d.

You have to stop macro recording by hitting q after :w<Enter>. Otherwise, the @d and every command after that has the usual behavior and gets added to the macro ad infinitum...

Adrian said...

Adding to my previous comment...

If you forget to stop macro recording with q, and then hit @d...can you say infinitely recursive macro execution?

To illustrate: Start with an empty buffer, then type the following in sequence:

qd - Start recording to macro buffer d

aThis is a test.<Enter><Esc> - Insert a single test line.

@d - Execute macro in buffer d. But wait, you're still recording the macro...

<Ctrl-C> - Stop the madness. 8-)

The Author said...

Oops you're totally right, you have to hit 'q' to stop the macro recording.

The Author said...

Hehe yeah, you can have a macro recursively trigger itself - I can't think of anything useful you can use that for. Presumable you can also trigger other macros - or copy/paste from buffers, etc.

Richard said...

>> I can't think of anything useful you can use that for

check out recursive macros :
http://vim.wikia.com/wiki/Record_a_recursive_macro

Nick Bishop said...

Not all versions of vi accept q to start recording macros, particularly ancient versions (like on SCO & Tru64).

For these, you have to type the characters into a line and yank these characters into a named buffer.

Tricky: you insert control characters (like esc and return) into the line by preceding that keystroke with ^V (Control-V).

The good oil is here: Web Archive copy