インタラクティブ指定子
refenerce を見ると *interactive-specifier-alist* に追加すればとか keymap.l 参照とか書いてあるので見てみたり調べてみたりしたのでメモ。
えーと、*interactive-specifier-alist* に '(キー . 関数のシンボル) を追加すれば キー の文字が指定子として使えるようになり、その指定子を指定された interactive なコマンドを実行すると、指定された関数が呼び出される。
その関数は
- 引数として以下が与えられる
- プロンプト文字列: (interactive "Tprompt") なら "prompt"
- :defaultN に与えられたもの
- :historyN に与えられたもの
- :titleN に与えられたもの
- (list 引数としたい値) を返すべし
今回はいくつかのキーワードシンボルからどれかを選ぶようなのが欲しかったので。
(defun interactive-keyword-symbol (prompt default history title) (multiple-value-bind (candidates must-match) (cond ((listp title) (values title t)) ((and (symbolp title) (listp (symbol-value title))) (values (symbol-value title) t)) (t (values nil nil))) (list (intern (completing-read prompt candidates :history history :default default :must-match must-match) (find-package "keyword"))))) (pushnew '(#\K . interactive-keyword-symbol) *interactive-specifier-alist* :test #'equal)
「いくつかのキーワードシンボル」をどうやって渡そうか困ったのだが、使い道のわからない :titleN を流用して、候補を与えられたらその中から(:must-match t)、そうでなけりゃなんでも、としておいた。default と history はふつーに使える。
(defun foo (arg) (interactive "Kfoo? " :default0 "foo" :title0 '(:foo bar baz)) arg)
M-x foo するとミニバッファに "foo? foo" となって、foo bar baz から補完とかできる。