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

Date: 2020-05-26
URL: https://s.conao3.com/blog/2020/609573
Author: conao3 (Naoya Yamashita)

ネタ元はEmacs-jp。

> namnium  06:43
> すみません、とても小さい質問なのですが、検索ワードが思いつかなかったので質問させてください。
> yasnippetでキーバインド C-x i i  をスニペット挿入に割り当てたところ、今まで使用していた insert-file C-x i  を打てなくなってしまったのですが、このようにキーバインドを途中で打ち切りたくなった時はどうすればいいのでしょうか?
> とりあえず現在は M-x insert-file  で諦めています&hellip;
> 
> conao3  08:18
> インタラクティブなら、C-x i iにnilをバインドした後にC-x iを再バインドします。
> インタラクティブでなくていいなら、init.elの該当行を削除して再起動するだけです。
> 
> namnium  09:48
> 両立って無理な感じですか?
> 
> conao3  09:50
> うーん、、独自にキーを待つ関数をC-x iに登録したら実現できるかもしれませんが、、

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

```emacs-lisp
(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-enable` を `nil` に設定することで止めます。

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

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