KeyboardMacrosTricks

''Use Keyboard Macros''

When I need to make the same kind of change to a number of similar entities, I use a keyboard macro.

For instance, I once used an Emacs keyboard macro to reduce the content of a HTML table down to gnuplot’s input format (to plot the data). I once used Emacs macro to translate Ruby code to Scheme code, by adding parenthesis at the right places. I was once debugging somebody else’s code, and their debugging output was generating lots of noise that did not pertain to the bug. Instead of spending time to discover how the debugging output was generated, I used Emacs macro to search and remove the noise from the output. I once needed to write a C switch() statement for an enumerated type. I copied the list of enumerated constants from the header file to my .c file, and recorded a keystroke macro that converts “MY_CONSTANT” into “case MYCONSTANT: break”. I used keyboard macros to manipulate this page. I changed all the bold asterisks into into ... markers.

Emacs macro are a powerful one-shot text-processing tool. It can do a lot of file-munging that you would do otherwise with a throw-away Perl script or Awk script.

A powerful keyboard macro idiom

This method leaves the TextCursor positioned at the beginning of a search target, which means that you can see what will be changed should you again invoke the macro. If you find the cursor positioned at a point you do not wish to change, C-s C-s repeats the last search of the macro and will move you to the next likely modification point. Of course, when merely changing successive lines it may not be necessary to search at all. Simply writing the macro so it moves the cursor to the next line may be adequate.

How To Use Keyboard Macros

You tools for this are:

The basic steps of the method are:

Advice and tricks

Here are a few tricks to get the most out of Emacs macros:

         (define-key global-map [f4] 'call-last-kbd-macro)
         (define-key global-map [\M-f2] 'apply-macro-to-region-lines)

Saving a macro

Emacs provides a number of functions to save macros for use in future sessions:

M-x kmacro-name-last-macro, bound to C-x C-k n, gives a command name to the last defined macro. As explained above, the macro can then be called by typing M-x name-of-the-macro.

M-x insert-kbd-macro asks for the name of a macro and inserts its definition at point. The use is to insert the definition in the .emacs init file, so that the macro will be ready for use in future sessions.

I use the following code to automate the process:

  (defun save-macro (name)
    "save a macro. Take a name as argument
     and save the last defined macro under
     this name at the end of your .emacs"
     (interactive "SName of the macro: ")  ; ask for the name of the macro
     (kmacro-name-last-macro name)         ; use this name for the macro
     (find-file user-init-file)            ; open ~/.emacs or other user init file
     (goto-char (point-max))               ; go to the end of the .emacs
     (newline)                             ; insert a newline
     (insert-kbd-macro name)               ; copy the macro
     (newline)                             ; insert a newline
     (switch-to-buffer nil))               ; return to the initial buffer

Put it in your .emacs file. You can then save your last macro by typing M-x save-macro.

ELisp in Macros

Emacs macro can also make use of simple Elisp expressions to take care of situations too complex for normal keyboard macros.

A good example is the need to create, say, a list of hostnames that differ by a number added to the first component:

   * hostname1.lm.com
   * hostname2.lm.com
   * hostname3.lm.com

Before starting the macro, I set an Elisp variable to 1:

 M-: (setq x 1)

M-: evaluates an Lisp expression. In this case it simply create a variable call x assigns it the value 1.

Then I start recording a macro, type “hostname,” then insert the variable’s value:

 C-u M-: x

The prefix C-u instruct M-: to insert the result of the evaluation at the point. Then I increment the variable:

 M-: (setq x (+ x 1))

then finish typing *.lm.com^J*. Now, I’ve got a macro that will insert a new unique hostname each time I invoke it. With an argument of 50, I’ve got 50 unique hostnames in a snap.

I find it easier in cases like these to use Registers:

C-u 1 C-x r n a ;; put 1 in register a
C-x (           ;; start macro
hostname        ;; type hostname
C-x r i a       ;; insert register a
C-e             ;; end of line
C-x r + a       ;; increment register a
.lm.com<RET>    ;; finish typing hostname
C-x )           ;; finish keyboard macro

I have even used this method along with a calc buffer to increment in hex.

Keyboard macros do have a counter feature: EmacsKeyboardMacroCounter, although it is apparently very recent. (Since I can’t find any online copy of the info file with it in it…

Use Macro counter

  01. C-x C-k C-a  to set the incrementing number
  02. C-x C-k C-f  to set the output format.  %02d for example
  03. C-x (        to start the recording
  04. C-x C-k C-i  to insert the counter
  05. C-x )        to end the recording
  06. C-x C-k C-c  to set the count 

  Then you are ready to go.  For example, you can choose a
  region and use 
  07. C-x C-k r to run it at each complete line

The index is generated in this way actually.
gejun

You can also do incrementing list using increment-register function.

If you want to produce this list:

test1
test2
test3
...

Do like this:

C-x r n q           (store the number 1 in register q)
C-x (               (start macro recording)
test C-x r i q      (insert contents of register q)
C-x r + q           (increment register q by 1)
RET                 (new line)
C-x )               (stop macro recording)

If you want to increment by more than one step at a time, send a prefix argument to C-x r +

Make a keyboard macro out of your lossage

You can create a macro out of your last 100 keystrokes. Type C-x C-k l.

If you want to define a kbd macro, you dont necessarily need to C-x ( ... C-x ). you can simply do what you wanted to do, and hit C-x C-k l afterwards. This presents you with your last 100 keystokes in a editable form. Simply fill in a name, and a keybinding, hit C-c C-c, and you are done.

One caveat is that this doesn’t work when there are mouse or frame events in the lossage buffer. Only pure keyboard events are supported.

I find it a good idea to use C-q to insert electric characters while recording a macro. This makes them execute faster (at least on my very slow machine). – PiotrMieszkowski

Really Dumb Question

Is there a way to convert an existing keyboard macro to elisp code?

The use-case for such a facility would be to explore the way emacs works internally. In cough MS Office cough applications, you can discover much about the object model from recording macros (though the comparison may be unfair). – ChristopherSmith

You can do this with M-x insert-kbd-macro but the result is probably not to your liking. If I do:

 C-x (
 C-n
 foo
 C-x )
 M-x name-last-kbd-macro RET newline-and-foo
 M-x insert-kbd-macro RET newline-and-foo RET

emacs will insert the following into the buffer:

 (fset 'newline-and-foo
   "\C-nfoo")

I would very much like to be able to insert something like this:

  (defun newline-and-foo ()
    (interactive)
    (next-line)
    (insert "foo"))

But it appears emacs does not have this feature.(2017 update: emacs does have this feature in a package called elmacro. [see bottom of page]) A casual glance at the source for insert-kbd-macro in macros.el would suggest that the best way to go about this would be to write a function that called (key-binding) on each key it was about to insert and inserted the corresponding function name instead. -avar.

edit-kbd-macro lists the names of the commands used in the function. With some regexing you could turn this into a function. Better yet, look in edmacro.el and write a function that writes the function.

The following package https://github.com/Silex/elmacro can record macros as elisp.