This is the first in a series of real world uses of emacs keyboard macros. Emacs macros are normally mentioned as a powerful feature of emacs, but many times I find the examples that are given are more academic in nature and don’t drive home their usefulness. These posts will show examples of macros “in the wild.” Part of the fun of becoming proficient with macros is that it both allows you to quickly complete a mundane task, and at the same time provides a bit of a mental exercise because you must think through the process for generalizing the task at hand.
For the uninitiated, an emacs macro allows you to record your keystrokes and lisp function calls so that you can replay them. Additionally, the macro facility has the ability to do recursive editing. This means you can pause your macro, edit the text, and then restart the recording of the macro. I find recursive editing useful for handling areas of a macro that I can’t generalize for each call of the macro.
C-x (– Start recording macro
C-x )– Stop recording macro
C-u C-x q– Pause macro so that you can recursively edit
C-x e– End macro and execute (emacs 22)
I have the following set in my
(global-set-key [f7] 'call-last-kbd-macro)
I might remove this and go with the kmacro keymaps that have been defined in emacs 22, but for now my brain is wired to hit f7. This allows me to quickly recall the last keyboard macro that I have defined.
I am a disgruntled java developer by day. I work projects that normally require soup to nuts knowledge. The other day I needed to modify some jsp pages to better handle changing references to a page and deployment at different context locations. The existing links in the jsp page were html anchor tags with relative urls such as:
<a href="foo.html">Foo</a>. The links to some of the pages are being “marketized” so the relative location of the page where the links show up is in flux (e.g, today it is /foo/blah.html, but tomorrow it will need to be /foo/widget/blah.html, and then two days from now it will be back to the original).
The not-so-fun way of doing this would be to incrementally search for “href=” and then change the link from:
<a href="<c:url value="/foo.html" />" >Foo</a>
c:url is part of the java standard tag library (JSTL) and takes care of the web application context issue discussed above.
Initially, I thought I might be able to use a regular expression search and replace to handle this task, but I also needed to edit some of the links as part of this process. Therefore, I chose to make a macro. When approached with a mundane task like this I normally goto a point in the buffer near the location where I need to start my task, think about the problem, develop my plan of attack, and then start the macro. In this case the general plan was:
- Incrementally search for
- Pause macro so that I could edit the URL if needed
- Restart macro
- Get back to the end of the
- Wrap the value of the href in
<c:url value="URL" />
- Stop recording the macro
- Replay the macro through the rest of the file
A great things about quick and dirty emacs macros is that you can make a mistake, back out your mistake, and fix the problem, and the few extra keystrokes that were added are immaterial when you run it. The following is an example of a quick one-off macro.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
C-s ;; isearch-forward href=" ;; self-insert-command * 6 RET ;; newline-and-indent C-SPC ;; set-mark-command C-u C-x q ;; kbd-macro-query C-x C-x ;; exchange-point-and-mark-nomark <c:url ;; self-insert-command * 6 SPC ;; self-insert-command value=" ;; self-insert-command * 7 C-s ;; isearch-forward > ;; self-insert-command RET ;; newline-and-indent <left> ;; backward-char-nomark />" ;; self-insert-command * 3 SPC ;; self-insert-command
You can see a macro in this format by using the command,