Record, play, re-play

Gentle reader Marc Donner has sent me an email sharing one of his favorite emacs hacks:

(global-set-key [f10]  'start-kbd-macro)
(global-set-key [f11]  'end-kbd-macro)
(global-set-key [f12]  'call-last-kbd-macro)

Yes, I could type C-x ( to start the macro and C-x ) to end the macro and C-x e to execute the macro, but that requires that my fingers be more nimble than they really are. Particularly because ( and ) are shifted keys.

This way I can start a macro with a single button push, finish it with another, and then repetitively run it by pressing a third button over and over.

As it happens, Emacs 22 comes with the functionality Marc assigns to his F12 key built-in: press just e right after executing the macro the first time, as many times as you need. There’s also the possibility of using a numerical prefix to specify how many times the macro should be executed (as in M-10 C-x e to execute it ten times), and passing zero as the prefix will keep on (re)executing it until the end of the buffer is reached.

One can also achieve macro re-plays with the command repeat, bound by default to C-x z. repeat works quite a bit like Vim’s ‘.': it, well, repeats the most recently executed command, and keeps repeating if you keep pressing z. So, instead of C-x e e e e e ..., one can C-x e C-z z z z.... Not as convenient, but this works in Emacs 21, and, besides, repeat is an interesting command on its own.

Saying that keyboard macro recording is a useful Emacs feature would be an understatement. You can record almost any Emacs operation and, therefore, keyboard macros can automate quite non-trivial tasks. For instance, i’ve just used them a couple hours ago to generate C function body stubs from their declarations in a header file. Just for the fun of it, here’s a screencast:

Note how you’re not limited to a single buffer, and how we use generic operations (like searching for next space to kill and yank the function’s return type). It’s also important to left the cursor in the right position for the next execution of the macro. At first you’ll make little mistakes, but fear not: you can actually edit the last recorded macro with kmacro-edit-lossage (Emacs 22 only). Just type C-xC-kl and you’ll be teletransported to a *Edit macro* buffer where you can edit your last keystrokes and record them as needed. Nifty, no?

As you get used to macros, you’ll surely discover many other tricks, but you can speed up your learning by means of the excellent pages KeyboardMacros and KeyboardMacrosTricks in the Emacs wiki. (One of my favourite tricks is using Elisp in macros to dynamically change what gets inserted). This Linux Journal article by Jesper Pedersen is also a good way to get you started as a power macro user.

Happy recording!

About these ads

11 Responses to “Record, play, re-play”

  1. Tim Lopez Says:

    My favorite Emacs trick with macros is to define a macro that modifies a line, highlight the target region, and then run the apply-macro-to-region-lines command. It often is easier than trying come up with the right regexp for a search/replace.

  2. rps Says:

    I’ve switched the parentheses with the brackets, which makes C-x ( easier (also, I can’t imagine coding Lisp if I had to shift for every paren).

  3. eclig Says:

    My favourite macro trick is the possibility of
    defining a macro “afterwards”, after you noted
    that you’ll be repeating a certain task over and over.

    At least in the CVS version of Emacs you can type “C-x C-k e” to edit a macro and it will ask you which macro you want to edit. You can respond to it with “C-h l” (like `view-losage’) and it will let you edit a macro consisting of the last 100 keys you pressed.

  4. Jan Hermanns Says:

    Why wasting 2 function keys? I think this is more elegant:

    ;; Toggle functionality
    (defvar my-kbd-macro nil “Holds kbd-macro”)
    (defun my-define-kbd-macro ()
    (interactive)
    (setq my-kbd-macro (not my-kbd-macro))
    (if my-kbd-macro
    (start-kbd-macro nil)
    (end-kbd-macro)))
    (global-set-key [f11] ‘my-define-kbd-macro)
    (global-set-key [f12] ‘call-last-kbd-macro)

  5. Greg Bakker Says:

    The pc builds I’ve been using (currently 23.0.0.1 alpha, previously 22.1 IIRC) bind by default F3 and F4 to start and end/playback-last respectively. Very handy.

  6. Amit Patel Says:

    I also use the technique Jan mentions, except I bind f5 to call-last-kbd-macro and (control f5) to my-define-kbd-macro. That way, I can think of f5 as The Macro Key, and when I use the modifier key, it lets me control the macro. Without the control key, I invoke the macro.

  7. MAH Says:

    What app did you use to display the keyboard presses on screen? That’s a really useful teaching tool! Creating videos of emacs in use, with the keypresses on screen like that would go some way to allowing remote emacs advocacy, letting people see and learn from emacs gurus that are not across the room. There’s a number of times when I’ve said to someone over email “you should use emacs”, but describing how you do something makes it sound rather long-winded and explaining all the keypresses so they can follow along if they become interested ends up hiding the fact that it is so efficient and quick. Describing the mechanics of how you do it gets in the way of the overall concept, but the on screen display there means that people can watch something and if something catches their eye they can then find out how it was done.

  8. Rob Wyrick Says:

    For a better emulation of the vi dot (‘.’), check out http://www.wyrick.org/source/elisp/dot-mode/

  9. Johannes Hüsing Says:

    So, instead of C-x e e e e e …, one can C-x e C-z z z z….

    This should be C-x z z z z …

  10. Note to self: Emacs macros « Günther Noack’s blog Says:

    [...] Also have a look at the Emacs wiki’s page on this and that nice article with video tutorial on that weblog on Emacs. [...]


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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: