keyconf.l で興味深い現象が起きていた

keyconf.l - 書き捨て御免 なんだけど

get-command-table (name)

name に関連づけられた hash-table を *command-tables-table* から取得(まだ無かったら作る)して返す、という関数。なんだけどせっかく作った hash-table を *command-tables-table* に保存してないので、毎回新たに hash-table を作ってしまう。たぶんやりたかったのはこう

(defun get-command-table (name)
  (or (gethash name *command-tables-table*)
      (setf (gethash name *command-tables-table*)
            (make-hash-table))))

define (name assocs key-binder)

要点だけ説明すると

  • cmds を get-command-table で取得した hash-table に束縛した環境を作り
  • その hash-table に assocs(キーワードとコマンドをたくさん)のキーワードとコマンドを保存しておいて
  • (キーワード . キー...) のリストを受けて、あるキーマップで キー... に「hash-table に保存されてるキーワードに対応するコマンド」をバインドする関数を定義する

というマクロ。
cmds が hash-table に束縛された環境内で関数を定義してるんで、定義された関数は cmds の束縛を含むクロージャになっている。だから *command-tables-table* には hash-table が保存されてなくても環境にある cmds の束縛で hash-table を参照できている。

emacs-lisp だとこれはできないよなぁ。