read-key-sequence
関数がキーシーケンス(キーシーケンス入力を参照)を読み取るときには、特定のイベントシーケンスを他のものに変換(translate)するために変換キーマップ(translation
keymaps)を使用します。input-decode-map
、local-function-key-map
、key-translation-map
(優先順)は変換キーマップです。
変換キーマップは他のキーマップと同じ構造をもちますが使い方は異なります。変換キーマップはキーシーケンスを読み取るときに、コンプリートキーシーケンスにたいするバインディングではなくキーシーケンスに行う変換を指定します。キーシーケンスが読み取られると、それらのキーシーケンスは変換キーマップにたいしてチェックされます。ある変換キーマップがkをベクターvにバインドするなら、キーシーケンス内のどこかにサブシーケンスとしてkが出現すると、それはv内のイベントに置き換えられます。
たとえばキーパッドキーPF1が押下されたとき、VT100端末はESC O
Pを送信します。そのような端末ではEmacsはそのイベントシーケンスを単一イベントpf1
に変換しなければなりません。これはinput-decode-map
内でESC
O Pを[pf1]
にバインドすることにより行われます。したがってその端末上でC-c
PF1をタイプしたとき、端末は文字シーケンスC-c ESC O
Pを発行して、read-key-sequence
がそれをC-c PF1に変換、ベクター[?\C-c
pf1]
としてリターンします。
変換キーマップは、(keyboard-coding-system
で指定された入力コーディングシステムを通じて)Emacsがキーボード入力をデコードした直後だけ効果をもちます。端末I/Oのエンコーディングを参照してください。
この変数は通常の文字端末上のファンクションキーから送信された文字シーケンスを記述するキーマップを保持する。
input-decode-map
の値は、通常はその端末のTerminfoかTermcapのエントリーに応じて自動的にセットアップされるが、Lispの端末仕様ファイルの助けが必要なときもある。Emacsには一般的な多くの端末の端末仕様ファイルが同梱されている。これらのファイルの主な目的はTermcapやTerminfoから推定できないエントリーをinput-decode-map
内に作成することである。端末固有の初期化を参照のこと。
この変数はinput-decode-map
と同じようにキーマップを保持するが、通常は優先される解釈選択肢(alternative
interpretation)に変換されるべきキーシーケンスを記述するキーマップを保持する。このキーマップはinput-decode-map
の後、key-translation-map
の前に適用される。
local-function-key-map
内のエントリーはマイナーモード、ローカルキーマップ、グローバルキーマップによるバインディングと衝突する場合には無視される。つまり元のキーシーケンスが他にバインディングをもたない場合だけリマッピングが適用される。
local-function-key-map
はfunction-key-map
を継承する。後者はすべての端末にバインディングを適用したい場合のみ修正するべきなので、ほとんど常に前者の使用が望ましい。
この変数は入力イベントを他のイベントに変換するために、input-decode-map
と同じように使用される別のキーマップを保持する。input-decode-map
との違いは、local-function-key-map
の前ではなく後に機能する点である。このキーマップはlocal-function-key-map
による変換結果を受け取る。
input-decode-map
と同様だがlocal-function-key-map
とは異なり、このキーマップは入力キーシーケンスが通常のバインディングをもつかどうかかに関わらず適用される。しかしこのキーマップによりキーバインディングがオーバーライドされても、key-translation-map
では実際のキーバインディングが効果をもち得ることに注意。確かに実際のキーバインディングはlocal-function-key-map
をオーバーライドし、したがってkey-translation-map
が受け取るキーシーケンスは変更されるだろう。明確にするためにはこのような類の状況は避けたほうがよい。
key-translation-map
は通常はself-insert-command
にバインディングされるような通常文字を含めて、ユーザーがある文字を他の文字にマップすることを意図している。
キーシーケンスのかわりにキーの変換として関数を使用することにより、シンプルなエイリアスより多くのことにinput-decode-map
、local-function-key-map
、key-translation-map
を使用できます。その場合にはこの関数はそのキーの変換を計算するために呼び出されます。
キー変換関数は引数を1つ受け取ります。この引数はread-key-sequence
内で指定されるプロンプトです。キーシーケンスがエディターコマンドループに読み取られる場合はnil
です。ほとんどの場合にはプロンプト値は無視できます。
関数が自身で入力を読み取る場合、その関数は後続のイベントを変更する効果をもつことができます。たとえば以下はC-c hをハイパー文字に後続する文字とするために定義する方法の例です:
(defun hyperify (prompt) (let ((e (read-event))) (vector (if (numberp e) (logior (ash 1 24) e) (if (memq 'hyper (event-modifiers e)) e (add-event-modifier "H-" e)))))) (defun add-event-modifier (string e) (let ((symbol (if (symbolp e) e (car e)))) (setq symbol (intern (concat string (symbol-name symbol)))) (if (symbolp e) symbol (cons symbol (cdr e))))) (keymap-set local-function-key-map "C-c h" 'hyperify)
キー変換関数は、非キーイベントを含んだキーシーケンス内のイベントにたいして、パラメーターにもとづいた調整を行いたいと考えるかもしれません。この情報は変数current-key-remap-sequence
から利用できます。この変数にはキー変換関数の呼び出し前後で変換されるキーのサブシーケンスがバインドされています。
そのキーシーケンスがコマンドにバインドされたとき、またはさらにイベントを追加してもコマンドにバインドされるシーケンスにすることができないとEmacsが判断したときにキーシーケンスの終わりが検出されます。
これは元のキーシーケンスがバインディングをもつかどうかに関わらず、input-decode-map
やkey-translation-map
を適用するときに、そのようなバインディングが変換の開始を妨げることを意味します。たとえば前述のVT100の例に戻って、グローバルマップにC-c
ESCを追加してみましょう。するとユーザーがC-c PF1をタイプしたとき、EmacsはC-c
ESC O PをC-c PF1に変換するのに失敗するでしょう。これはEmacsがC-c
ESCの直後に読み取りを停止して、O Pが読み取られずに残るからです。この場合にはユーザーが実際にC-c
ESCをタイプすると、ユーザーが実際にESCを押下したのか、あるいはPF1を押下したのか判断するためにEmacsが待つべきではないのです。
この理由によりキーシーケンスの終わりがキー変換のプレフィクスであるようなキーシーケンスをコマンドにバインドするのは、避けたほうがよいでしょう。そのような問題を起こす主なサフィックス、およびプレフィクスはESC、M-O (実際はESC O)、M-[ (実際はESC [)です。