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