web-dev-qa-db-ja.com

ENDキーにterminfoエントリがないのはなぜですか?

DebianシステムでENDキーを押すと^[[Fが生成されます:

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[F     27 0033 0x1b
         91 0133 0x5b
         70 0106 0x46

しかし、なぜこのキーコードがterminfoにないのですか?

$ infocmp -1 | grep end
kend=\EOF,

それにもかかわらず、ncursesはそれをKEY_ENDとして正しく認識します。どうやって?

TERMxterm-256colorです

ところで、kendだけではなくendendを使う動機は何ですか? (khomeおよびhomeについても同じ)

[〜#〜]編集[〜#〜]

JohanMyréenのコメントで述べたように、khome文字列はHomeキーを押すと生成されるシーケンスです。しかし、DebianではHomeキーを押すとhomeが生成されます。どうして?

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
$ infocmp -1 | grep home
    home=\E[H,
    khome=\EOH,
8
Igor Liferenko

JohanMyréenの答えは近いものでしたが、厳密には問題ではありません。使用するほとんどの端末エミュレータには、 normal application の特別なモードがありますキー。端末の説明はoneモード用に記述されています。これは、全画面アプリケーションが使用するものに対応しています。他のアプリケーション(インタラクティブShellなど)は通常、 application モードを使用するように画面を初期化しません。 Bashはその一例です。

normal モードでは、xtermおよび類似の端末が送信します escape[ (CSI) application モードの場合、キーパッドは escapeO (SS3)。 terminfo構文では、その escape \Eです。したがって、infocmpは、説明がアプリケーションモードを使用していることを示しています。 home機能が送信されますto端末、カーソルを home 位置に移動する方法を指示します(左上)khomeと同じではありません(送信されたfromキーボードを使用する端末)。

全画面アプリケーション(ncursesを使用するアプリケーションなど) may は、キーパッドを初期化するための端末機能文字列を送信します。端末の説明には、端末をアプリケーションモードにするものとそうでないものがあります。

kendendの使用は命名規則です。terminfoでは、慣例によりkで始まるすべての名前=特別なキー(ファンクションキー、カーソルキー、キーパッドキー)を参照し、これらがアプリケーションによって読み取られる文字列であることを明確にします。たとえば、kcub1(cursor-backward key)はcub1(カーソルを1列後ろに移動)とは異なります)。

ncursesはキーをKEY_ENDとして認識します。これは、使用しているアプリケーションが keypad 関数を呼び出し、smkx(ニーモニックは「キーボード送信モードの開始」を意味します)。実際にアプリケーションモードがオンになる場合とオンにならない場合があります。 Linuxコンソールの端末の説明にはありませんが、xtermにはあります。

原則として、モードを切り替えるために tput を使用できます(そしてshowkeyから異なる結果を取得します):

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
^C        3 0003 0x03
^D        4 0004 0x04
$ tput smkx
$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[OH     27 0033 0x1b
         79 0117 0x4f
         72 0110 0x48

厄介なことに、cursesは文字列の名前を1つだけ認識します。一部の端末(xtermなど)は、編集キーパッドのキーに異なる名前を使用して、古いハードウェア端末をエミュレートします。 xterm FAQ下にリストされている)では、「ホーム」キーに「挿入」という名前を付ける可能性があります...

参考文献:

10
Thomas Dickey

Homeキーの問題は、物理端末と、それをエミュレートする端末エミュレータには、通常モードとアプリケーションモードの2つのモードがあり、エスケープシーケンスは端末のモードによって異なります。Terminfoはこれにうまく対応しません。通常モード(別名「カーソルモード」)では、EndキーのエスケープシーケンスはESC [ F、アプリケーションモードでESC O F。この問題をググリングすると、全体の混乱が明らかになります。

編集 terminfoソースから:

「VT100シリーズ端末には、カーソル(「矢印」)キーがあり、カーソルモードとアプリケーションモードの2つの異なるモードで操作できます。カーソルモードはリセット状態であり、通常の状態と見なされます。アプリケーションモードは「セット」です。状態。カーソルモードでは、カーソルキーが「Esc [{code}」シーケンスを送信し、ANSI規格に準拠します。アプリケーションモードでは、カーソルキーが「Esc O」シーケンスを送信します。アプリケーションモードは、主に移植の補助として提供されました。 VT52アプリケーション。カーソルキーは通常カーソルモードであると想定されており、viなどのアプリケーションは常に文字列を送信することが想定されています。そのため、カーソルキーの定義は、文字列の送信後に端末が送信するものと一致するように作成されます。 。文字列がnull文字列であるか定義されていない場合、カーソルキーは「カーソルモード」であると見なされ、カーソルキーの定義はその仮定と一致する必要があります。そうでない場合、アプリケーションが失敗する可能性があります。また、アプリケーションは常に終了する前に文字列を端末に送信します。」

5
Johan Myréen