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


8

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。どうやって?

TERM です xterm-256color

ところで、単に持っているのkendではendなく、その背後にある動機は何endですか?(khomeおよびも同じhome

編集

JohanMyréenのコメントで述べたように、khomestringは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,

1
違いhomeとは、khomeということであるkhomeのに対し、文字列がホームキーを押す順序は、生成されたhome文字列がホーム位置にカーソルを移動する端末に送信する必要があるシーケンスです。私の知る限りでは、terminfoはend機能を定義していませんkend
JohanMyréen2017

@JohanMyréenカーソルの「ホームポジション」とは何かを例に説明していただけませんか?そしてなぜ端末はterminfoのkendよう\EOFに定義されていますか?これはDebianのterminfoのバグですか?それでも、ncursesはどのようにしてそれを検出できますか?\E[FKEY_END
Igor Liferenko 2017

ホームポジションは、画面の左上隅です。
JohanMyréen2017

回答:


10

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

ノーマルモード、xtermのと同様の端子送信escape[内(CSI)をしながら、アプリケーションモード、それらのキーパッドは、送信escapeO(SS3)。terminfo構文では、そのエスケープ\Eです。だから、infocmp説明がアプリケーションモードを使用することを示しています。home能力が送信されるまでにカーソルを移動させるためにどのようにそれを伝える、終端ホームポジション(左上)と同じではないkhome(送信からキーボードを用いて端末)。

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

kend対の使用はend命名規則です。terminfoの規則では、kで始まる名前はすべて、アプリケーションによって読み取られる文字列であることを明確にするために、特別なキー(ファンクションキー、カーソルキー、キーパッドキー)を指します。たとえば、kcub1(cursor-backward key)は(cursor-backward key)とは異なります(cursor-backward keycub1)。

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では、「ホーム」キーに「挿入」という名前を付ける可能性があります...

参考文献:


はい、keypad関数を使用しています。しかし、「どのようにncursesがそれをどのように検出するか」という質問では、KEY_END「どのようにkeypadデコード^[[Fするか」を意味しましたkendterminfoデータベースをkeypad使用してキーコードを解釈することを考えると)。私が正しく理解した場合、これはがカーソルモードであるために発生しますが、ncursesアプリケーションはアプリケーションモードです。showkey -a
Igor Liferenko 2017

showkey通常モードとアプリケーションモードを切り替えません。これはLinux固有のプログラムであり、ターミナルデータベースを使用するのではなく、Linuxコンソールを前提としています
Thomas Dickey

showkeyがモードを切り替えない場合は、呼び出されても、デフォルトの状態を使用します。ポイントは、私が混乱するのではなく、showkey版画^[[Fであるということ^[OFです。(私showkeyは、キーボードボタンを押すことによって端末によって送信されている実際のキーコードを視覚的に表すために使用しましたが、関係する微妙な点があることを疑うことはありません。)
Igor Liferenko

はい、それは「通常」モードです(これを参照する通常の方法)。もちろん、を使用tput smkxして端末を初期化し、異なる結果を得ることができます。
トーマスディッキー2017

lessユーティリティにはバグがあると思います。アプリケーションモードになりましたが、キーパッドのEnterキーの解釈に失敗しました。バグレポートを提出する必要がありますか?(これを確認するにはless、入力後にキーパッドのEnterキーを押して押します/ESCOM
。Enter

5

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

terminfoソースから編集

次に、カーソルキーは「カーソルモード」であると想定され、カーソルキーの定義はその想定と一致する必要があります。一致しない場合、アプリケーションが失敗する可能性があります。また、アプリケーションが終了する前に、常に文字列を端末に送信することも期待されています。」


「アプリモード」への切り替え手順は?ncursesによって行われますか?
Igor Liferenko 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.