Emacsでプレフィックスキーにバインドする方法

ネタ元はEmacs-jp。

namnium 06:43 すみません、とても小さい質問なのですが、検索ワードが思いつかなかったので質問させてください。 yasnippetでキーバインド C-x i i をスニペット挿入に割り当てたところ、今まで使用していた insert-file C-x i を打てなくなってしまったのですが、このようにキーバインドを途中で打ち切りたくなった時はどうすればいいのでしょうか? とりあえず現在は M-x insert-file で諦めています…

conao3 08:18 インタラクティブなら、C-x i iにnilをバインドした後にC-x iを再バインドします。 インタラクティブでなくていいなら、init.elの該当行を削除して再起動するだけです。

namnium 09:48 両立って無理な感じですか?

conao3 09:50 うーん、、独自にキーを待つ関数をC-x iに登録したら実現できるかもしれませんが、、

ということでEmacsにできないことはないので、実装してみた。

(leaf async-await
  :ensure t
  :config
  (leaf c/insert-file
    :leaf-defer nil
    :pre-setq ((c/insert-file-enable . t)
               (c/insert-file-delay . 1.0))
    :bind (("C-x i" . nil)
           ("C-x i i" . yas-insert-snippet))
    :config
    (funcall
     (async-lambda ()
       (while c/insert-file-enable
         (await (promise:delay c/insert-file-delay))
         (warn "%s" (prin1-to-string
                     (which-key--this-command-keys)))
         (when (equal [24 105] (which-key--this-command-keys))
           (warn "Detect: C-x i")
           (await (promise:delay c/insert-file-delay))
           (when (equal [24 105] (which-key--this-command-keys))
             (warn "Redetect: C-x i")
             (call-interactively #'insert-file))))))))
(setq c/insert-file-enable nil)

async-awaitとwhich-keyに依存しています。

ループを止める手段が用意されてないので、外から c/insert-file-enablenil に設定することで止めます。

あと call-interactivelyquit すると無限ループが止まってしまうんですが、なぜだろう。。

C-x i を打って、Redetectされる前に i を素早く入力すると、 yas-insert-snippet が実行されます。 Redetectされると insert-file が実行されます。