The following commands have all become essential in my day to day Emacs usage:
C-x ESC ESC (repeat-complex-command)
C-x C-e (eval-last-sexp)
I use them to define regular expressions for use in editing text documents. Over time, I begin to collect quite a few of these, so it makes sense to think more carefully about my key bindings: normally I just use a Function key, but there’s other stuff I want to hot key from there now…. The Emacs manual says that the combination of C-c followed by a plain letter is reserved for the user, so I can put my custom routines there with a single letter mnemonic to help me remember what’s what.
Here’s a macro (with an example of its use) for setting up these sorts of text processing routines:
(defmacro defreplacer (name description search-for replace-with chord) `(progn (defun ,name (n) ,description (interactive "p") (query-replace-regexp ,search-for ,replace-with nil (if (and transient-mark-mode mark-active) (region-beginning)) (if (and transient-mark-mode mark-active) (region-end)))) (global-set-key (kbd ,chord) ',name))) (defreplacer pull-text-from-semi-colons "Remove text from between two semi-colon signs." "[ ]*;\\([a-z]*\\);[ ]*" ; use double back slash to 'escape' in quotes "\\1" "C-c ;")
In the example above, we’re replacing lower case text inside a pair of semi-colons (and surrounded with any number of spaces on each side) with just the lower case text. The command chord to trigger that replace routine is “C-c ;”. This is a pointlessly simple example, but it should give you the basic idea of how to use the macro.
Does the “defmacro” really do much more for us than “defun” would otherwise do? The main savings you get with the macro is that it defines the key binding at the same time that the replacement function is defined– having a naming type there caused me a minor headache when I was wondering why my hot-keys weren’t working once. With “defmacro” you eliminate the chance of this kind of confusion occurring. On the other hand, if you change the definition of the macro after a file has been loaded, you will not change the operation of the existing functions– the macro only affects the environment at compile time. So there are trade offs either way. In this case I went with a macro because once I get my regular expression from re-builder, I wanted to be able to write the code for everything as quickly as possible. With “defreplacer”, all I needed was four arguments and I was good to go.