Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

TorgoX (1933)


"Il est beau comme la retractilité des serres des oiseaux rapaces [...] et surtout, comme la rencontre fortuite sur une table de dissection d'une machine à coudre et d'un parapluie !" -- Lautréamont

Journal of TorgoX (1933)

Wednesday March 01, 2006
08:46 PM

A keybinding convenience-macro for emacs

[ #28842 ]
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

    (zerop (length body))
     ; no params at all
    (and (= 1 (length body))
     (null (car body))))
     ; one param: nil
   (list 'global-unset-key key))

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

  (t (error
   "I don't understand this onkey parameter: %s"

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • 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. :)

    • Randal L. Schwartz
    • Stonehenge
  • 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 []