Dear Log,
The thing that I do endlessly in my .emacs.config is set key
bindings. And until recently, it was endless amounts of
verbosely repetitive
(global-set-key "\M-x" 'this_command)
and
(global-set-key "\M-y" '(lambda () (interactive)
(this) (that) (the-other))) and
(global-unset-key "\M-z"). It was awful.
It finally occurred to
me to simplify things a bit with a single macro,
"onkey"
so that I can do (onkey "\M-x" 'this_command) and
(onkey "\M-y"
(this) (that) (the-other)) and
(onkey "\M-z" nil).
It's my first Lisp macro, and it is scary.
And here it is:
(defmacro onkey (key &rest body) (cond
((or
(zerop (length body))
; no params at all
(and (= 1 (length body))
(null (car body))))
; one param: nil
(list 'global-unset-key key))
((and
; symbolp doesn't work nicely in
; macros, it seems. So we fake it.
(= 1 (length body))
(listp (car body))
(string-equal (caar body) 'quote))
(list 'global-set-key key (car body)))
((listp (car body)) ; commands
(list 'global-set-key key
(append '(lambda () "~keyfunction~"
(interactive)) body)))
;Otherwise...
(t (error
"I don't understand this onkey parameter: %s"
body))))
I'd just leave out the length 1 check too. If you have (quote fred barney), you're already pretty crazy.
You might prefer(list 'global-set-key key
(append '(lambda () "~keyfunction~"
(interactive)) body)))
Basically, backquote starts a list you can interpolate into; comma interpolates a single item; comma + at-sign splices in a list at that point. As usual, more info in BackquoteSyntax.`(global-set-key key
,@(append '(lambda () "~keyfunction~"
(interactive)) body)))
-Dom