GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Translation-Keymaps.html ・ emacs-doc.conao3.com

23.15 イベントシーケンスを翻訳するためのキーマップ

read-key-sequence 関数がキーシーケンスを読み取る際(キーシーケンス入力を参照)、変換キーマップを使用して、特定のイベントシーケンスを別のシーケンスに変換します。変換キーマップは、input-decode-map、local-function-key-map、key-translation-map(優先順位順)です。

翻訳キーマップは他のキーマップと同様の構造を持ちますが、用途が異なります。完全なキーシーケンスに対するバインドではなく、キーシーケンスの読み取り時に行う翻訳を指定するものです。各キーシーケンスが読み込まれるたびに、それぞれの翻訳キーマップと照合されます。もしいずれかの翻訳キーマップが k をベクトル v にバインドしている場合、キーシーケンスのどこであっても k が部分シーケンスとして出現するたびに、その部分シーケンスは v のイベントに置き換えられます。

例えば、VT100端末では、キーパッドのキー PF1 が押されると 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] として返します。

翻訳キーマップは、Emacsが(keyboard-coding-systemで指定された入力コーディングシステムを用いて)キーボード入力をデコードした後にのみ有効になります。ターミナル入出力エンコーディングを参照してください。

変数: input-decode-map

この変数には、一般的なキャラクタ端末においてファンクションキーから送信される文字シーケンスを記述したキーマップが格納されています。

input-decode-map の値は通常、端末の Terminfo または Termcap エントリに基づいて自動的に設定されますが、場合によっては端末固有の Lisp ファイルによる補助が必要になります。Emacs には多くの一般的な端末向けの端末固有ファイルが用意されており、その主な目的は、Termcap や Terminfo から推論できる範囲を超えて input-decode-map にエントリを追加することにあります。端末固有の初期化 を参照してください。

変数: local-function-key-map

この変数は、input-decode-mapと同様のキーマップを保持していますが、通常は優先される別の解釈に変換されるべきキーシーケンスを記述している点が異なります。これはinput-decode-mapの後、key-translation-mapの前に適用されます。

local-function-key-map 内のエントリは、マイナーモード、ローカル、またはグローバルキーマップで設定されたバインディングと競合する場合、無視されます。つまり、元のキーシーケンスに他にバインディングが設定されていない場合にのみ、リマッピングが適用されます。

local-function-key-map は function-key-map を継承します。後者を変更するのは、すべてのターミナルでバインディングを適用したい場合に限られるため、ほとんどの場合、前者を使用する方が好ましいです。

変数: key-translation-map

この変数は、input-decode-mapと同様に入力イベントを別のイベントに変換するために使用されるもう一つのキーマップです。input-decode-mapと異なる点は、local-function-key-mapの前ではなく後に動作を開始することであり、local-function-key-mapによる変換結果を受け取ります。

Just like input-decode-map, but unlike local-function-key-map, this keymap is applied regardless of whether the input key-sequence has a normal binding. Note however that actual key bindings can have an effect on key-translation-map, even though they are overridden by it. Indeed, actual key bindings override local-function-key-map and thus may alter the key sequence that key-translation-map receives. Clearly, it is better to avoid this type of situation.

key-translation-map の意図は、通常 self-insert-command に割り当てられている一般文字も含め、ユーザーが一方の文字セットをもう一方にマッピングできるようにすることにあります。

input-decode-map、local-function-key-map、key-translation-map を単なるエイリアスとしてではなく、キーシーケンスの代わりに関数をキーの変換先として用いることができます。その場合、この関数が呼び出されて、当該キーの変換先が算出されます。

key 翻訳関数は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 から取得でき、この変数はキー翻訳関数の呼び出し前後で、翻訳対象となるキーサブシーケンスにバインドされます。

23.15.1 通常のキーマップとの相互作用

キーシーケンスの終了は、そのキーシーケンスがコマンドにバインドされているか、あるいは、これ以上のイベントが発生してもコマンドにバインドされたシーケンスに至ることはないとEmacsが判断したときに検出されます。

つまり、input-decode-map や key-translation-map は、元のキーシーケンスにバインディングがあるかどうかにかかわらず適用されるものの、そのようなバインディングが存在する場合でも、依然として変換が行われない可能性があります。例えば、先ほどの VT100 の例に戻り、グローバルマップに C-c ESC のバインディングを追加してみましょう。すると、ユーザーが C-c PF1 を押したとき、Emacs は C-c ESC の直後にキーの読み取りを停止し、O P を後回しにするため、C-c ESC O P を C-c PF1 にデコードできなくなります。これは、ユーザーが実際に C-c ESC を押した場合を想定したものであり、その場合、Emacs はユーザーが本当に ESC を押したのか PF1 を押したのかを判断するために、次のキーを待って待機し続けるべきではありません。

そのため、キーシーケンスの末尾がキー変換の接頭辞となっているようなキーシーケンスに、コマンドをバインドすることは避けたほうがよいでしょう。こうした問題となる主な接尾辞/接頭辞には、ESC、M-O(実際にはESC O)、およびM-[(実際にはESC [)があります。