Emacs の Prefix Key とお約束ごと


私は Windows 10 の環境で xyzzy というエディタを利用しております。xyzzy は Emacs ライクなキーバインドですので、Windows のメモ帳や他のテキストエディタ、通常利用するショートカットキーと比べても、独特のキー入力を求められます。

1 ストロークで終わるキーバインドを覚えるのもしんどいですが、 C-x C-nM-x x などの 2 ストロークの入力を必要とするキーバインドを覚えるはさらにしんどいです。それぞれどういう意図があってアサインされてるんや……、と思ったのがこのエントリーのきっかけです。
Emacs キーバインドには何かしらお約束ごとやルールがあって、それが分かれば苦労は減るだろうと思って調べました。

2 ストロークキーバインドの Prefix Key

Emacs キーバインドは 2 ストローク のキー割り当てがあります。あるキーを押した後(1 ストローク目)、別なキー入力(2 ストローク目)を押した時に発動するコマンドがある、という意味です。
この 1 ストローク目のキーは Prefix Key (プレフィックスキー)と呼ばれます。 ※ このエントリーの中では、"Prefix Key" と英語での呼称に統一します。
特によく使う Prefix Key には、下記があります。

  • C-x : ctl-x-map
  • Esc : esc-map
    • Esc が Prefix Key か、もしくは Alt キー(メタキー)を装飾キーにしたキーバインド(こっちは 1 ストローク)
  • C-c : mode-specific-map

参考

C-h でヘルプ表示を行うの Prefix Key help-map がありますが、割愛いたします。恐らく、大抵の人は C-h は Backspace に割り当てすると思うので。ctl-x-4-mapgoto-map などのキーもありますが、こちらも割愛します。

C-x に続くキー "ctl-x-map"

C-x が Prefix Key となるキーバインドは、Emacs では ctl-x-map と呼ばれます。編集系のコマンドもありますが、Emacs 本体を操作するコマンドが多くアサインされているようです。
この C-x に続くキーにコマンドを何かで割り当てようとすると、既存のキーと被る可能性があります。不特定多数に配布するメジャーモードのキー割り当てに理由なくアサインするのは、不適切になります。

C-c に続くキー "mode-specific-map"

C-c が prefix key となるキーバインドは、Emacs では mode-specific-map と呼ばれます。 メジャーモードのコマンドを実行するため の prefix key です。

https://www.gnu.org/software/emacs/manual/html_node/elisp/Prefix-Keys.html
Mode-specific-map is the global keymap for the prefix key C-c . This map is actually global, not mode-specific, but its name provides useful information about C-c in the output of C-h b (display-bindings), since the main use of this prefix key is for mode-specific bindings.

C-c 以降に割り当てられているキーは、動作している現在のメジャーモードによって、キーに割り当てられているコマンドが違います。 C-c C-d が、html-mode ではカーソル付近のタグを削除する動作をしますが、また違うメジャーモードの場合、そのメジャーモード専用のコマンドが割り当てをされています。

"mode-specific-map" についてのお約束ごと

さて、Lisp プログラム(Elisp)を書く上で、この C-c に続くキーについてお約束があります。StackExchange に、有識な方がご回答されてました。

「あなたの好きなようにキー設定は変更できる」という前置きの元ですが、「あなたが Emacs のライブラリ(Elisp)にてキーバインドを変更するコードを書き、それを他人に配布する場合、Elisp のマニュアルに書かれている Key Binding Conventions の内容がルールである」とのことです。それでは該当のページを見てみましょう。

一部コメントを付けまして、C-c の "mode-specific-map" についての箇所を抜粋します。

  • Lisp でのプログラムで C-c letter をキーバインドとして割り当ててはいけません( letter は大文字・小文字の両方です)。これはユーザーが自由に割り当ててよいキーとして予約されており、被らせてはいけません。
    • letter とはコントロールキーを伴わない大文字・小文字のアルファベットです。 C-c hC-c A など。(筆者注釈)
    • C-c C-a などはセーフです。メジャーモードで割り当てが可能なキーです。(筆者注釈)
  • C-c に続く制御文字(Enter など)と数字キーは、 メジャーモード用に予約されております。
  • C-c に続く { } < > : ; もメジャーモード用に予約されております。
    • 例えば C-c {` などです。(筆者注釈)
  • C-c に続く ASCII 文字以外、または記号文字はマイナーモードのために割り当てられています。メジャーモードでそれらの割り当てをすることは完全には禁止されておりませんが、それを行った場合、マイナーモードの割り当てがオーバーライド(shadowed)することがあります。

Elisp を書く場合、このようなルールを守る必要があります。

Esc に続く、もしくは Alt (メタ)キーを装飾キーにしたキー "esc-map"

Esc に続く、もしくは Alt (メタ)キーを装飾キーにしたキーバインドは、Emacs では esc-map と呼ばれます。Ctrl を装飾キーにしたコマンドの補完の意味合いが強いように見えます。
Alt キーを装飾キーにすることでワンストロークでコマンドを実行できますが、個人的に Alt キーの位置はキーボード上で迷子になりがちなので、Esc を Prefix Key にしてコマンド実行する場合が多いです。
"ctl-x-map" のキーマップ同様、不特定多数に配布するメジャーモードのキー割り当てに理由なくアサインするのは、不適切になります。

その他のキー

同様に D.2 Key Binding Conventions から一部抜粋です。

  • 修飾キーを伴わない F5 から F9 のファンクションキーも、ユーザーが自由に割り当ててよいキーとして予約されています。
  • C-h をどのような prefix key の後には割り当ててはいけません。 C-c のキーバインドの後も含みます。Prefix key の後の C-h は、その Prefix key のサブコマンドのヘルプ表示を行います。
  • Esc で終わるキーバインドを割り当ててはいけません。ただし Esc の次が Esc で終わるキーバインドを除きます。(Esc Esc は問題ないということです)
    • C-c Esc は NG ということです。(筆者注釈)
  • 同様に、 C-g で終わるキーバインドも設定してはいけません。これも、キーシーケンスをキャンセルするのに通常利用されるためだからです。

キー一覧を見たい

M-x describe-bindings で一覧を見ることができます。xyzzy も同様です。

まとめ

Emacs で頻出して良く使う 2 ストロークのキーバインドは、

  • C-x : Emacs 本体を操作するコマンドがアサインされていることが多い。
  • Esc (もしくは Alt キーを装飾キーとする 1 ストローク): Ctrl を装飾キーにしたコマンドの補完の意味合いが強いように見えます。
  • C-c : メジャーモードを操作する。

がほとんどです。あまり意識したことはなかったのですが(気付かなかったとも言えます)、 C-c はメジャーモード用というのが分かったのが、調べていく中で一番の収穫でした。