この質問は以下からインスピレーションを得ました。vi.SEに関するもう一つの質問。 OPには、実行時に+ShiftキーF8の組み合わせに問題があります。端末エミュレータがそれを正しく渡していないため(少なくとも私がデバッグしたものでは)キーの組み合わせは機能しません。vim
urxvt
vim
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。私がするなら:vim
urxvt
:map <f8> :echo "yay"<CR>
を押すと「ああ」が正しくエコーされますF8。
答え1
端末とアプリケーション間のインタフェースは、キーではなくバイトを送信します。印刷可能文字は、端末の文字符号化に対応するバイト列として解釈される。ファンクションキーはエスケープシーケンスでエンコードされます。これらのエスケープシーケンスには一般的な規則がありますが、完全に標準化されていません。
より一般的な背景については、以下を参照してください。キーボード入力とテキスト出力はどのように機能しますか?。詳細については、次を参照してください。コンソールログイン画面で上矢印を押すと^[[Aが表示される理由はありますか?そしてキーバインディングテーブル?
すべてのファンクションキーエスケープシーケンスは次から始まります。エスケープ文字そしてほとんどは~
。 Vimは、コンパイル時の設定と端末情報に基づいて複数のエスケープシーケンスを認識します。 Vimがエスケープ文字列を認識しない場合、これは無視されますが、Vimはエスケープ文字列の長さを知りません(最後の文字がaであるとは思わず、必ずしも~
そうではありません)。~
Vimが認識する部分の後にはしばしば混乱が発生し、時にはより混乱します。
シェルまたはVimの挿入モードで最初に+を押すと、端末がCtrl送信する内容を正確に表示できます。V
Vimにエスケープシーケンスに対応するファンクションキーを知らせることができます。:set
、例えば
:set <S-F8>=^[[19;2~
(後の部分を^[
端末が実際に送信する内容に置き換えてください)。
答え2
一部のキーは次のように使用されます。修飾子(shift、controlが最も一般的に使用されます。)端末エミュレータは一連のXイベント、を使って見ることができますxev
。ターミナルエミュレータはshiftaXライブラリを使用して、ファンクションAキーやカーソルキー(と呼ばれる)などのいくつかのイベントを統合します。「特殊キー」)Xライブラリには事前定義された変換はありません。ターミナルエミュレータはこれらの修飾子を使用して、特別なキーで送信されたさまざまなエスケープシーケンスを生成するかどうかを決定します。
様々な端末エミュレータは、これに対して異なる規則を使用することができる。なし基準転送できるシーケンスです。ただ条約たとえば、特定の端末をエミュレートするか、他の端末にはない新しいシーケンスを作成して拡張することにします。
rxvtとxtermはどちらもこれらの修飾子を使用して異なるファンクションキーシーケンスを提供するため、端末に数十のファンクションキーがあるかのように端末でプログラムを実行できます。
ただし、端末には次のものがあります。モデル、アプリケーションから端末までの制御シーケンスによって設定されます。変化ファンクションキーに対して送信されたエスケープシーケンス。 vimのような全画面プログラムでは、これらのモード切り替え制御シーケンスを使用するのが一般的です。だからあなたは違いを見ることができます。
なぜなら何もないから基準、一つあります。端末の説明各端末の動作を説明します(TERM
環境変数を使用)。ほとんどの端末では、初期化時に使用する端末について説明します。申請方法(キーボードとカーソルキー用) フルスクリーンアプリケーションは、これらの初期化シーケンスを使用し、これらの説明に記載されているファンクションキーとカーソルキーを使用して一貫した動作を取得します。
すべての端末がファンクションキーのエスケープシーケンスを送信するわけではありません。例えば、アルトスワークステーションはカラットを使用します。ワイズ-858ビットモード(\233
CSI \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~
特別な違いはありません。
追加資料:
- ShiftまたはControl修飾子を使用するには?(ncurses FAQ)
- カーソルキーが機能しない(ncurses FAQ)