次: , 前: Input Modes, 上: Terminal Input


37.8.2 入力イベントの変換

本節では、入力イベントをキー列の一部になるまえに別の 入力イベントに変換する機能について述べます。 これらの機能は、ここに述べる順に各イベントに適用されます。 つまり、各イベントはまずextra-keyboard-modifiersに従って修正され、 つぎに(適切ならば)keyboard-translate-tableを介して変換され、 最後に指定されているキーボードコーディングシステムで復号化されます。 キー列の一部として読み取られるイベントであると、 読み取られるキー列に追加され、それを含む部分キー列を まずfunction-key-mapで検査してから、 つぎにkey-translation-mapで検査します。

— 変数: extra-keyboard-modifiers

この変数は、Lispプログラムがキーボード上の 修飾キーを『押す』ことができるようにする。

1
<SHIFT>キー。
2
<LOCK>キー。
4
<CTL>キー。
8
<META>キー。

ユーザーがキーボードのキーを打つたびに、 ビットマスクで指定した修飾キーが押し下げられているかのように キーを修正する。

ウィンドウシステムを使っているときには、 プログラムは任意の修飾キーを『押す』ことができる。 さもなければ、<CTL>と<META>のキーのみを 仮想的に押すことができる。

— 変数: keyboard-translate-table

この変数は、キーボード文字の変換表である。 これにより、コマンドのバインディングを変更せずに、 キーボードのキー配置を変更できる。 その値は普通は文字テーブルであるか、あるいは、nilである。

keyboard-translate-tableが文字テーブルであると、 キーボードから読み取った各文字をこの文字テーブルで探す。 みつけた値がnil以外であると、 実際の入力文字のかわりにその値を使う。

つぎの例では、keyboard-translate-tableに文字テーブルを設定する。 そして、文字C-sC-\C-qC-^を入れ換える。 これ以降、C-\を打つとC-sを打った効果があり、 その逆もそうである。 (この話題に関しては詳しくは、see Flow Control。)

          (defun evade-flow-control ()
            "Replace C-s with C-\ and C-q with C-^."
            (interactive)
            (setq keyboard-translate-table
                  (make-char-table 'keyboard-translate-table nil))
          
            ;; C-sC-\を入れ換える
            (aset keyboard-translate-table ?\034 ?\^s)
            (aset keyboard-translate-table ?\^s ?\034)
          
            ;; C-qC-^を入れ換える
            (aset keyboard-translate-table ?\036 ?\^q)
            (aset keyboard-translate-table ?\^q ?\036))
     

この変換は、端末から読み取った文字に最初に行われる変換である。 recent-keysのような記録機能やドリブルファイルは、 変換後の文字を記録する。

— 機能: keyboard-translate from to

この関数は、文字コードfromを文字コードtoに変換するように keyboard-translate-tableを変更する。 必要ならばキーボード変換表を作成する。

残りの変換機能は、読み取ったキー列の部分列を変換します。 それらはread-key-sequenceに実装されていて、 read-eventで読む入力には効果はありません。

— 変数: function-key-map

この変数は、普通の文字端末上のファンクションキーが 送出する文字の列を記述したキーマップを保持する。 このキーマップは他のキーマップと同じ構造であるが、使い方が異なる。 キー列のバインディングではなく、 読み取りつつあるキー列を変換する方法を指定する。

function-key-mapがキー列kを ベクトルvに『バインド』すると、 キー列のどこにkが現れても、 vのイベントで置き換える。

たとえば、端末VT100は、キーパッドのキー<PF1>を押すと <ESC> O Pを送出する。 したがって、Emacsではこの列を1つのイベントpf1に変換したい。 VT100を使っているときにfunction-key-mapにおいて <ESC> O P[pf1]に『バインド』すれば、 これを行える。

つまり、C-c <PF1>を打つと 文字の列C-c <ESC> O Pが送出される。 のちに関数read-key-sequenceがこれをC-c <PF1>に戻し、 ベクトル[?\C-c pf1]を返す。

マイナモード/ローカル/グローバルのキーマップに矛盾するような function-key-map内の項目は無視される。 この意図は、ファンクションキーが送出する文字の列には それ独自のキーバインディングがあるべきではなく、 もしあったとしても、もとの定義を優先することである。

function-key-mapの値は、 端末のterminfoやtermcapの情報に従って自動的に普通は設定されるが、 端末固有のLispファイルの助けが必要な場合もある。 Emacsには、一般的な多くの端末向けの端末固有ファイルがある。 それらの主目的は、terminfoやtermcapから推定できないものを function-key-mapに定義することである。 see Terminal-Specific

— 変数: key-translation-map

この変数は、function-key-mapと同様に 入力イベントを別の入力イベントへ変換するために用いる別のキーマップである。 function-key-mapとは2つの意味で異なる。

key-translation-mapの意図は、 self-insert-commandに普通はバインドされる通常の文字を含めて ユーザー向けに文字集合を別の文字集合に 対応付けられるようにすることである。

キーの『変換として』キー列のかわりに関数を用いると、 function-key-mapkey-translation-mapは 単なる配置替え以上のことに使えます。 その関数で当該キーの変換を計算するのです。

キー変換関数は1つの引数を受け取ります。 その引数は、read-key-sequenceで指定されたプロンプトか、 エディタコマンドループがキー列を読み取っている場合にはnilです。 多くの場合、プロンプトの値は無視できます。

関数自身が入力を読むときには、 後続のイベントを変更することもできます。 たとえば、後続の文字をハイパー文字にするC-c hの定義は つぎのようになります。

     (defun hyperify (prompt)
       (let ((e (read-event)))
         (vector (if (numberp e)
                     (logior (lsh 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)))))
     
     (define-key function-key-map "\C-ch" 'hyperify)

set-keyboard-coding-systemを用いた キーボード文字集合の復号化を有効にしているときには、 上に述べた変換を終えてから復号化を行います。 See Specifying Coding Systems。 Emacsの将来の版では、他の変換のまえに復号化を行うでしょう。