new article on emacs keyboard macro as well as elisp code.
• 〈Emacs Keyboard Macro and Examples〉
plain text version follows
Emacs Keyboard Macro and Examples
Xah Lee, 2010-11-16
This page shows a example of real world use of emacs keyboard macro
system, and a emacs lisp example.
Emacs has a feature that lets you record a sequence of keystrokes. I
learned the basics since i started to use emacs in 1998, but actually
never used it much, maybe few times a year. Since 2007, i learned the
command “apply-macro-to-region-lines”, which made it more useful.
Still, i use it perhaps once a month. However, when you use it, it
saves you hours for doing the job.
First, let's see what it does.
How to record a sequence of keystrokes?
To record keystrokes, press 【Ctrl+x (】 (kmacro-start-macro), then
start typing your keystrokes. When done, press 【Ctrl+x )】 (kmacro-end-
macro). This records your keystrokes.
To run the keystrokes you've recorded, press 【Ctrl+x e】 (kmacro-end-
and-call-macro) or call “apply-macro-to-region-lines”.
Command Name Key
start-kbd-macro 【Ctrl+x (】
end-kbd-macro 【Ctrl+x )】
call-last-kbd-macro 【Ctrl+x e】
Saving Your Keyboard Macro for Future Use
If you want to use your keyboard macro (kmacro) for future use, you
can save it. To save the macro:
* (1) Call “name-last-kbd-macro”.
* (2) call “insert-kbd-macro”. This will insert the lisp code for
the kmacro at the cursor point.
* (3) Put the code in your emacs init file.
* (4) Then, you can execute your kmacro like this: 【Alt+x
Turn Off line-move-visual
When you record keystrokes, it is better that the arrow up/down keys
move the cursor thru a logical line, as opposed to visual line. (Emacs
23's default is visual line.) To set to logical line, call “set-
variable”, then give “line-move-visual”, with value “nil”. (“t” for
true; “nil” for false).
When you play back macro, be sure the “line-move-visual” is the same
as when you recorded it.
Example of Actual Use
Here's a example of how i use keyboard macro. Usually, i use macro
about once or few times a month. When you need it, it is extremely
time saving. Otherwise you might spend hours doing it, or even if you
know elisp well.
Today, i have about 60 lines. Each line is a url, like this:
I need it to be like this:
• 〈Mathematical Models of 3D Inputs Control〉
Where the first line is the title of that page.
I have 60 other lines like this:
I've written a elisp code that turns a url on my site into the format
i want. Here's the lisp code:
(defun xah-cite ()
"Change the file path under cursor into title and path.
For example, this line
• 〈Xah's Emacs Tutorial〉
The title came from HTML file's title tag.
File path must be a url scheme, full path, or relative path.
Example url schemes among browsers and OSes
C:\\Users\\xah\\web\\xahlee_org\\emacs\\emacs.html ; ie
file:///C:/Users/xah/web/xahlee_org/emacs/emacs.html ; firefox
file:///C:/Users/xah/web/xahlee_org/emacs/emacs.html ; google chrom
file:///C:/Users/xah/web/xahlee_org/emacs/emacs.html ; safari
file://localhost/C:/Users/xah/web/xahlee_org/emacs/emacs.html ; opera
file:///Users/xah/web/xahlee_org/emacs/emacs.html ; safari
file:///Users/xah/web/xahlee_org/emacs/emacs.html ; firefox
file://localhost/Users/xah/web/xahlee_org/emacs/emacs.html ; opera
Example full path variations
This is Xah Lee's personal command assuming a particular dir
(let (bds ff title)
(setq bds (bounds-of-thing-at-point 'filename))
;; change file path to full path
(setq ff (replace-regexp-in-string "^http://www\\." "http://" ff))
(setq ff (replace-regexp-in-string "/$" "/index.html" ff))
((string-equal system-type "windows-nt") ; Windows
(replace-regexp-in-string "^http://xahlee\\.org/" "c:/
((string-equal system-type "darwin") ; Mac
(replace-regexp-in-string "^http://xahlee\\.org/" "/Users/
(setq ff (local-url-to-file-path ff))
(setq ff (expand-file-name ff ))
(if (string-match ".+html\\'" ff)
(delete-region (car bds)
(insert "• 〈" title "〉\n" (xah-web-path-to-url ff))
I have defined a alias for this command to save me typing, because i
use it often. Alias is defined like this:
(defalias 'c 'xah-cite)
So, to call my command, i type 【Alt+x c Enter】 (Actually i type “Alt
+a” instead of “Alt+x”, because i'm using ErgoEmacs Keybinding.). This
can easily change each line to the format i want. But there are 60
lines! So, a keyboard macro comes to use. Here's how i do it.
* Move cursor to the beginning of first url.
* Type 【Ctrl+x (】 to start recording.
* Type 【Alt+x c Enter】. To change the line to the way i want.
* Type Enter to insert a blank line.
* Type → to move to the beginning of next url.
* Type 【Ctrl+x )】 to end macro recording.
Then, i select all lines that has not been processed, then call “apply-
macro-to-region-lines”. Then all lines becomes this:
• 〈Logitech G13 Advanced Gameboard (Review)〉
• 〈Chinese Pinyin Letter Frequency and Dvorak Layout〉
• 〈Logitech Trackball Mouse Reviews〉
• 〈Review Of Microsoft SideWinder Gaming Mouses〉
• 〈Trackball Mouse Reviews〉
Emacs is fantastic!
In keyboard macro, you can call any emacs command, or even more than
one command. Emacs's kmacro feature simply play back the keystrokes.
In general, kmacro is extremely useful whenever you need to do
something repeatitive and the steps are the same. It is a great time-
saver. You do not need to know elisp to use it. Even if you are a
elisp master, many repeatives jobs are still best done with a kmacro.
With kmacro, i can finish this job in 30 seconds. But if i were to
write a elisp for it, it easly can take 30 min.