ターミナルエミュレータはShift + Fキーをどのように処理しますか?

ターミナルエミュレータはShift + Fキーをどのように処理しますか?

この質問は以下からインスピレーションを得ました。vi.SEに関するもう一つの質問。 OPには、実行時に+ShiftキーF8の組み合わせに問題があります。端末エミュレータがそれを正しく渡していないため(少なくとも私がデバッグしたものでは)キーの組み合わせは機能しません。vimurxvtvim

F端末エミュレータがキーをどのように処理するのかわかりません。

存在するurxvt

  • Shift+を押すとF8 ~エコーが鳴ります。
  • F7(または他のFキー)を押すと~エコーされます。

vim内部urxvt

  • Shift+を押すとF8効果が表示されます~~
  • Shift+を押すとF7効果が表示されます~
  • Shift+を押すとF6効果が表示されます~~~

一方xterm

  • Shift+を押すとF8 ;2~エコーが鳴ります。
  • F8(または他のFキー)を押すと~エコーされます。

なぜこのような結果が出るのか理解できません。

追加のデバッグのために実行して、xev次のような結果を得ました。

~のためF8

KeyPress event, serial 29, synthetic NO, window 0x2000001,
    root 0x7e, subw 0x0, time 17730758, (431,256), root:(432,275),
    state 0x0, keycode 74 (keysym 0xffc5, F8), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

Shift

KeyPress event, serial 32, synthetic NO, window 0x2000001,
    root 0x7e, subw 0x0, time 17733031, (431,256), root:(432,275),
    state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

そして右側にShift

KeyPress event, serial 32, synthetic NO, window 0x2000001,
    root 0x7e, subw 0x0, time 17733372, (431,256), root:(432,275),
    state 0x0, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

しかし、私はそこでまったく奇妙なものを見ませんでした。

端末エミュレータはこれらのキー(Fキー)をどのように処理しますか?ターミナルエミュレータは何から情報を受け取りますかx11?内部で実行されているプログラムにどのように渡しますか?

私はいつもFキーがEsc数字を追加するだけの組み合わせだと思いました。今私は私が間違っていたことがわかりました。


付録

そこではFキーが正しく機能しませんShift。私がするなら:vimurxvt

:map <f8> :echo "yay"<CR>

を押すと「ああ」が正しくエコーされますF8

答え1

端末とアプリケーション間のインタフェースは、キーではなくバイトを送信します。印刷可能文字は、端末の文字符号化に対応するバイト列として解釈される。ファンクションキーはエスケープシーケンスでエンコードされます。これらのエスケープシーケンスには一般的な規則がありますが、完全に標準化されていません。

より一般的な背景については、以下を参照してください。キーボード入力とテキスト出力はどのように機能しますか?。詳細については、次を参照してください。コンソールログイン画面で上矢印を押すと^[[Aが表示される理由はありますか?そしてキーバインディングテーブル?

すべてのファンクションキーエスケープシーケンスは次から始まります。エスケープ文字そしてほとんどは~。 Vimは、コンパイル時の設定と端末情報に基づいて複数のエスケープシーケンスを認識します。 Vimがエスケープ文字列を認識しない場合、これは無視されますが、Vimはエスケープ文字列の長さを知りません(最後の文字がaであるとは思わず、必ずしも~そうではありません)。~Vimが認識する部分の後にはしばしば混乱が発生し、時にはより混乱します。

シェルまたはVimの挿入モードで最初に+を押すと、端末がCtrl送信する内容を正確に表示できます。V

Vimにエスケープシーケンスに対応するファンクションキーを知らせることができます。:set、例えば

:set <S-F8>=^[[19;2~

(後の部分を^[端末が実際に送信する内容に置き換えてください)。

答え2

一部のキーは次のように使用されます。修飾子shiftcontrolが最も一般的に使用されます。)端末エミュレータは一連のXイベント、を使って見ることができますxev。ターミナルエミュレータはshiftaXライブラリを使用して、ファンクションAキーやカーソルキー(と呼ばれる)などのいくつかのイベントを統合します。「特殊キー」)Xライブラリには事前定義された変換はありません。ターミナルエミュレータはこれらの修飾子を使用して、特別なキーで送信されたさまざまなエスケープシーケンスを生成するかどうかを決定します。

様々な端末エミュレータは、これに対して異なる規則を使用することができる。なし基準転送できるシーケンスです。ただ条約たとえば、特定の端末をエミュレートするか、他の端末にはない新しいシーケンスを作成して拡張することにします。

rxvtとxtermはどちらもこれらの修飾子を使用して異なるファンクションキーシーケンスを提供するため、端末に数十のファンクションキーがあるかのように端末でプログラムを実行できます。

ただし、端末には次のものがあります。モデル、アプリケーションから端末までの制御シーケンスによって設定されます。変化ファンクションキーに対して送信されたエスケープシーケンス。 vimのような全画面プログラムでは、これらのモード切り替え制御シーケンスを使用するのが一般的です。だからあなたは違いを見ることができます。

なぜなら何もないから基準、一つあります。端末の説明各端末の動作を説明します(TERM環境変数を使用)。ほとんどの端末では、初期化時に使用する端末について説明します。申請方法(キーボードとカーソルキー用) フルスクリーンアプリケーションは、これらの初期化シーケンスを使用し、これらの説明に記載されているファンクションキーとカーソルキーを使用して一貫した動作を取得します。

すべての端末がファンクションキーのエスケープシーケンスを送信するわけではありません。例えば、アルトスワークステーションはカラットを使用します。ワイズ-858ビットモード(\233CSI \033[)の使用をサポートします。qnx使用される\377。しかし、ほとんどスタートASCII エスケープ文字を使用します。最終キャラは別の話です。半分くらいrxvtの修正機能キーASCIIチルダ以外の文字で終わります~(これを説明するncurses FAQにテーブルがあります)。これらの違いにより、端末記述が実際の端末と一致することが重要です。

現在のバージョンのvim(7.3)では問題がないと思います。シフトを認識しますF8。数年前に問題が発生しました。 vimのファンクションキーチェックには、xtermが送信するようにセミコロンは必要ありません。セミコロンに会うと、ファンクションキーの認識が停止します。以前のバージョンのvimを使用しているか、一部のキーマッピングがキーの押下を認識するのを妨げる可能性があります。 vimは今可能ですが(使用しているバージョンに関係なく)いいえ拡張キーの端末記述を表示しますが、独自のテーブルに依存しています。問題を複雑にするために、vim可能xterm機能(と呼ばれる)を使用してください。tcap クエリ) は xterm が送った実際のキーシーケンスを取得します。

一方、vimにはrxvtキーシーケンスに対して異なる結果を提供するマップがあります。シフトF6\E[29~)、シフトF7\E[31~)、シフトF8()の間に\E[32~特別な違いはありません。

追加資料:

関連情報