A keybinding convenience-macro for emacs

TorgoX on 2006-03-02T01:46:29

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))))


Guessing on that symbolp

merlyn on 2006-03-02T01:52:31

The reason it doesn't work is because you don't have a symbol. You have a cons cell containing a quote and the symbol.

I'd just leave out the length 1 check too. If you have (quote fred barney), you're already pretty crazy. :)

Interpolation

Dom2 on 2006-03-02T07:55:50

Emacs has a syntax for interpolation which you might find easier. Instead of:
(list 'global-set-key key
    (append '(lambda () "~keyfunction~"
     (interactive)) body)))
You might prefer
`(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.

-Dom