Naming and saving macros for repetitive tasks

Any time you find yourself doing a repetitive task in emacs, you should stop and think about whether you could be using a macro to automate it. To use a macro you start a recording and do whatever edits or other commands you need for your task, then stop the macro and execute it to repeat the task as many times as you like. There is a great introduction and overview of macros at emacs-fu.

I wanted to pick out from that article a useful feature of macros that I have neglected until recently. Normally a macro is saved until you record a new one, in which case it is overwritten. However it is possible to give your macro and name and then save it for future use.

At the moment I am rewriting some LaTeX notes into org mode to use in lecture slides. This involves several repetitive tasks, like converting a section heading like this

\subsection{Object on vertical spring}

into this

** Object on vertical spring

The trick to making a good macro is to make it as general as possible, like searching to move to a character instead of just moving the cursor. In this case I did the following:

  1. Start with the cursor somewhere on the line containing the subsection and hit C-x C-( to start the macro recording
  2. C-a to go to the start of the line
  3. C-SPC to set the mark
  4. C-s { to search forward to the “{” character
  5. RET to exit the search
  6. C-d to delete the region
  7. Type “** ” to add my org style heading
  8. C-e to move to the end of the line
  9. BACKSPACE to get rid of the last “}”
  10. C-x ) to end the recording

Now I can replay my macro with C-x e but I know I’ll need this again many times in the future so I use M-x name-last-kbd-macro and enter a name for the macro (e.g. bjm/sec-to-star). Now I go to my emacs config file and add the following

;;macro to convert latex sections to org-mode subheadings
;;use M-x insert-kbd-macro to add the following line
(fset 'bjm/sec-to-star
   [?\C-a ?\C-  ?\C-s ?\{ return ?\C-d ?* ?* ?  ?\C-e backspace ?\C-x])

;;bind this to a key
(global-set-key (kbd "C-c b *") 'bjm/sec-to-star)

Where the fset line was added by using M-x insert-kbd-macro and then selecting the macro name I just used to save the macro. Finally I bind this to a key for ease of use in the future.

You can use M-x edit-named-kbd-macro to see a nicer view of your macro and tweak it if needed.

Finally, note that macros are not limited to simple editing commands. You can e.g. create, edit and save new files or do other more complex procedures within a macro.