Next: , Up: 入力の読み取り   [Contents][Index]


22.8.1 キーシーケンス入力

コマンドループはread-key-sequenceを呼び出すことによって、キーシーケンスの入力を一度に読み取ります。Lisp関数もこの関数を呼び出すことができます。たとえばdescribe-keyはキーを記述するためにこの関数を使用します。

Function: read-key-sequence prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop

この関数はキーシーケンスを読み取って、それを文字列かベクターでリターンする。この関数は完全なキーシーケンスに蓄積されるまで、つまりカレントでアクティブなキーマップを使用してプレフィクスなしでコマンドを指定するのに十分なキーシーケンスとなるまでイベントの読み取りを継続する(マウスイベントで始まるキーシーケンスは、カレントバッファーではなくマウスのあったウィンドウ内のバッファーのキーマップを使用して読み取られることを思い出してほしい)。

イベントがすべて文字で、それらがすべて文字列に適合すれば、read-key-sequenceは文字列をリターンする(文字列内へのキーボードイベントの配置を参照)。それ以外なら文字、シンボル、リストなどすべての種類のイベントを保持できるベクターをリターンする。文字列やベクターの要素は、キーシーケンス内のイベント。

キーシーケンスの読み取りには、そのイベントを変換するさまざまな方法が含まれる。イベントシーケンス変換のためのキーマップを参照のこと。

引数promptはプロンプトとしてエコーエリアに表示される文字列、プロンプトを表示しない場合はnil。引数continue-echoが非nilなら、それは前のキーの継続としてそのキーをエコーすることを意味する。

元となる大文字のイベントが未定義で、それと等価な小文字イベントが定義されていれば、通常は大文字のイベントが小文字のイベントに変換される。引数dont-downcase-lastが非nilなら、それは最後のイベントを小文字に変換しないことを意味する。これはキーシーケンスを定義するときに適している。

引数switch-frame-okが非nilなら、たとえ何かをタイプする前にユーザーがフレームを切り替えたとしても、この関数がswitch-frameを処理すべきではないことを意味する。キーシーケンスの途中でユーザーがフレームを切り替えた場合、またはシーケンスの最初だがswitch-frame-oknilのときにフレームを切り替えた場合、そのイベントはカレントキーシーケンスの後に延期される。

引数command-loopが非nilなら、そのキーシーケンスがコマンドを逐次読み取る何かによって読み取られることを意味する。呼び出し側が1つのキーシーケンスだけを読み取る場合には、nilを指定すること。

以下の例ではEmacsはエコーエリアにプロンプト‘?’を表示して、その後ユーザーがC-x C-fをタイプする。

(read-key-sequence "?")

---------- Echo Area ----------
?C-x C-f
---------- Echo Area ----------

     ⇒ "^X^F"

関数read-key-sequenceはquitを抑制する。この関数による読み取りの間にタイプされたC-gは他の文字と同じように機能し、quit-flagをセットしない。quitを参照のこと。

Function: read-key-sequence-vector prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop

これはread-key-sequenceと同様だが、キーシーケンスを常にベクターでリターンして、文字列では決してリターンしない点が異なる。文字列内へのキーボードイベントの配置を参照のこと。

入力文字が大文字(またはシフト修飾をもつ)でキーバインディングをもたないものの、等価な小文字はキーバインディングをもつ場合には、read-key-sequenceはその文字を小文字に変換します(この挙動はユーザーオプションtranslate-upper-case-key-bindingsnilにセットして無効にできる)。lookup-keyはこの方法によるcase変換を行わないことに注意してください。

入力を読み取った結果がシフト変換(shift-translation)されていたら、Emacsは変数this-command-keys-shift-translatedに非nil値をセットします。シフト変換されたキーにより呼びだされたときに挙動を変更する必要があるLispプログラムは、この変数を調べることができます。たとえば関数handle-shift-selectionはリージョンをアクティブ、または非アクティブにするかを判断するためにこの変数の値を調べます(handle-shift-selectionを参照)。

関数read-key-sequenceもマウスイベントのいくつかを変換します。これはバインドされていないドラッグイベントをクリックイベントに変換して、バインドされていないボタンダウンイベントを完全に破棄します。さらにフォーカスイベントとさまざまなウィンドウイベントの再配置も行うため、これらのイベントはキーシーケンス中に他のイベントととも出現することは決してありません。

モードラインやスクロールバーのような、ウィンドウやフレームの特別な箇所でマウスイベントが発生したとき、そのイベント型は特別なことは何も示さずにマウスボタンと修飾キーの組み合わせを通常表すのと同じシンボルになります。ウィンドウの箇所についての情報はイベント内の別のどこか、すなわち座標に保持されています。しかしread-key-sequenceはこの情報を仮想的なプレフィクスキーに変換します。これらはすべてシンボルでありtab-lineheader-linehorizontal-scroll-barmenu-bartab-barmode-linevertical-linevertical-scroll-barleft-marginright-marginleft-fringeright-fringeright-dividerbottom-dividerです。これらの仮想的なプレフィクスキーを使用してキーシーケンスを定義することにより、ウィンドウの特別な部分でのカウスクリックにたいして意味を定義できます。

たとえばread-key-sequenceを呼び出した後にそのウィンドウのモードラインをマウスでクリックすると、以下のように2つのマウスイベントが取得されます:

(read-key-sequence "Click on the mode line: ")
     ⇒ [mode-line
         (mouse-1
          (#<window 6 on NEWS> mode-line
           (40 . 63) 5959987))]
Variable: num-input-keys

この変数の値は、そのEmacsセッション内で処理されたキーシーケンスの数である。これには端末からのキーシーケンスと、実行されるキーボードマクロによって読み取られたキーシーケンスが含まれる。