@kyanny's blog

流行はつねに前進していく。そして、精神の偽りの自由が絶えずせり上がっていく - ロマン・ロラン

anything 中に anything を起動しないようにキーバインドを修正した

(define-key anything-map (kbd "C-;") 'anything-exit-minibuffer)

として解決。

以下、経緯とか何をして結論にたどり着いたかなどをダラダラと書く。

俺は C-; を anything に割り当てている。数日前に anything.el ほかを auto-install-batch でアップデートしたら(数ヶ月前のファイルを使ってた) C-; C-; と連打したらヘンになってしまうようになった(なんかヘンになったとしか説明できてない時点で事態を正しく把握できてない証拠だ)。 C-g でキャンセルして元みていたバッファに戻れない。気づいてなかったけど C-; を連打する癖があったみたいで、気になりだしたら他のことが手につかなくなってしまったので調べて回避した。 anything を更新する前は C-; C-; は anything がキャンセルされてたので、元の挙動に戻したかった。

そもそも自分でも何が問題でどうすれば解決するのかわかっていなかったので、ぐぐっても有益な情報にたどりつけなかった。 Twitter でつぶやいていたら id:rubikitch さんからコメントをもらった。「anything 中に anything する操作は想定されていない、 anything-nest を使え」

ということで anything-nest を調べた。ぐぐっても全然引っかからないのでソースを読んだ。関数定義をみても起動の仕方がよくわからなかったので anything-other-buffer の関数定義と見比べて anything を直に呼ぶときの引数指定を真似して適当に define-key して実行してもうまく動かない。 anything 中じゃないとダメっぽいので C-; と違うキーに割り当てて anything 中に実行させてみたけどうまくいってるかわからない。とりあえず望んでる挙動ではなさそうだということはわかった。

いろいろソースを読んでたらひらめいた。 anything 中に C-; を押したとき C-g を押したのと同じ挙動になればいいのだから C-g に何が割り当てられてるか調べて anything-map で C-; を上書きすればいい。ここでようやく正解っぽい方向が定まったので M-x describe-key C-g を調べると keyboard-quit が割り当てられてたので (define-key anything-map (kbd "C-;") 'keyboard-quit) などとするがうまくいかない。

本当に keyboard-quit なのかよ?と疑問に思い keyboard-quit に edebug をかけて実行してみると、やはり anything 中に C-g を押してもデバッガが起動しない。どうやら違う関数が割り当てられてるらしい。しかし anything 中は M-x describe-key が実行できない。 M-x と打てないので、調べようがない。

仕方ないので anything.el と anything-config.el のソースで define-key してるところを読んで C-g を見つけたら anything-isearch-map で C-g に関数を割り当ててるところがあったので真似してみたが、これも違う。これは anything 中に isearch した場合に C-g で isearch をキャンセルする関数を割り当ててるところで、見たまんま map が違うじゃん、という話だった。

anything.el のソースを読んだり M-x describe-function anything してるうちに、ついに anything-map そのものを開いて読むところまで到達した。いよいよ本丸、ここにどのキーを押したときどの関数が呼ばれるか全て書いてあるので、ここから C-g の割り当てを探せばいい。でもこれが簡単にはいかなかった。関数はちゃんと書いてあるんだけど肝心のキー割り当てのほうが、 (7 keymap (18 . funcname)) みたいになってて読めない。 7 とか 18 とかもっと大きな数字とか、マジックナンバーだらけ。オンラインマニュアルの Keymap のページを流し読みしてみたけど数字と文字の対応表みたいなものは見つけられず。当然どういうキーワードで検索すればいいか見当もつかないので、ぐぐっても成果なし。

最終的に、関数を全部目視して exit とか quit とか cancel とかそれっぽい名前の関数をピックアップして、それぞれ anything-map の C-; に上書きして試すしかないか、と諦めて最初に試したやつが当たりだった。

いまだにこの、 18 とかいうマジックナンバーが何なのかわからない。 Javascript でキーイベント判定に使う KeyCode とかとも違うようだし。こういうのいったいどうやって調べたらいいんだろう。マニュアル片っ端から読むしかないのだろうか。なんかもうちょっと効率のいい Emacs と Emacs Lisp の勉強の仕方はないものかな。