1回のキーを押すと何バイトを返すことができますか?メタキーはもっと返すべきですか?

1回のキーを押すと何バイトを返すことができますか?メタキーはもっと返すべきですか?

私はこのツールを使ってきました。読者入力最近の。現在は、実行中に押すすべてのキーについてstdoutにレポートを印刷していますが、うまくいくようであれば、すぐにより高い目的にアップグレードしたいと思います。これまでにはいくつかの利点があります。

  1. すべての出力は単一パイプの複数の同時プロセスの結果です。
  2. 各キーを押した直後に各キーの押しを解釈して報告します。
  3. それ(私の知る限り)キーを押すたびに送信されたバイト数を報告します。

たとえば、実行して次のキー/キーの組み合わせを順番に押すと...

  1. a
  2. CTRL+J
  3. ALT+SPACE
  4. UP
  5. ALT+UP

...キーを押すたびに1行ずつ、キーを押すたびにすぐに端末画面に次のものを印刷します。

 a:97
 \n:10
 \240:160
 \e:27 [:91 A:65
 \e:27 [:91 1:49 ;:59 5:53 A:65

...各キーを押す各バイトは次のように印刷されます。

<space>(printable char|\C-escape|\octal-escape):[decimal byte value]

…私の考えにはそれが適切だと思います。

しかし、それらのいくつかは私を混乱させます。

  1. すべてのキーを試してみたようで明示的にstty8ビット文字を送信するように設定しましたが、(インポートするcs8ALT+のSPACE組み合わせは、ASCIIの10進数127以上の構成バイトを報告する唯一の組み合わせのようです。
    • ALT修飾子と関係があると思ったので、特に混乱しています。飛ぶ(私はこの概念についてほとんど知らないことを認めます)キーシーケンスですが、他のすべての場合、ALT+は単にシーケンスプレフィックスを付ける anykeyか、すでにエスケープされているシーケンスを微妙に変更します。ESC
    • しなければならないALT いいえ送信されたシーケンスをより高い128〜255の範囲に移動しますか?
    • (以下のderobertのコメントでは、読者はマルチバイトUTF-8composeシーケンスを正常に解釈して報告しました。) 注:以下に設定されているlocaleすべてのカテゴリを報告します。LC_*en_US.UTF-8
  2. また、懸念されるのは、各キーを押すためのすべてのバイトを取得するようですが、現在の形式では、私のスクリプトはキーを8バイト(現在最大32バイト)に分割します。
    • 私は前に考えた8バイトそれだけで十分ですが、今は別のロケールのマルチバイト文字を私が見たより長いエスケープシーケンスと組み合わせることができるかどうかを考えると懐疑的です。だからバッファを拡張しました。しかし、もともと私に与えられた8バイトほど決定的ではありません。
    • 1回のキー押しで送信できるバイト数に上限はありますか?

答え1

これは実際にいくつかの質問です。一部は端末固有の動作を処理し、一部は組み合わせを処理します。

Altまず、修飾語として使用されるときに予想される行為に関する質問があります。一部の人は、Altキー(多くのキーボードに表示される)をキーMeta(端末キーボードに表示されることはほとんどありません)と同じです。一部の人々はさらに、エスケープ文字と同じです。呼ぶ伝統的な使用。少なくともxtermでは関連付けを設定できます(なぜならパッチ番号 122, 1999metaSendsEscape、リソースがありますパッチ番号225、2007追加altIsNotMetaaltSendsEscapeリソース)。他の端末エミュレータ(およびそのユーザー)は柔軟性がありません。だからそこに習慣これはエスケープとメタと同じです。コンベンションは標準ではありません。

メタキーのロギング動作は次の場所にあります。terminfo(5) マニュアルページ:

端末にいる場合「メタキー」送信された文字の8番目のビットを設定するShiftキーとして機能するという事実を使用できます。km。それ以外の場合、ソフトウェアはビット8がパリティビットであると仮定し、通常はクリアされます。この「メタモード」をオンまたはオフにする文字列がある場合は、次のように指定できます。smmそしてrmm

メタモードがオフの場合、標準動作(慣例のみあり)はありません。

eightBitInputxtermのリソースに応じて、128を超えるメタキーコンストラクタを使用できます。例えば、パッチ番号 183, 2003、この変更は、メタモードが違法なUTF-8を生成するのを防ぐために行われました。

  • UTF-8モードでEveryBitInputリソース処理を変更し、値をUTF-8に変換します。それ以外の場合は、違法なUTF-8コードがアプリケーションに送信されます(Bram Moolenaarレポート)。

ただし、通常、端末と端末で使用できるほとんどのエスケープシーケンスは、伝統的なキーボードから返されるエスケープシーケンスは7ビットASCIIを使用します。 VT100も例外ではありません。2002年パッチ番号177:

  • 誤った制御シーケンス検出を改善するためにパーサーテーブルを変更して、xtermが実際のDEC端末のように動作するようにします(Paul Williamsパッチ)。

つまり、パーサーテーブルは次のようになります。最大組織は入力文字の8番目の数字を無視します。他の端末ではこの側面を無視できますが、まだxtermキーボードで使用されているエスケープシーケンスをコピーします。結果はあなたです最大7ビットASCIIを参照してください。

あなたが見るべきほとんどの動作はxtermで始まるので、xtermを例として使用しています。維持するrxvtから)。 xtermを使用すると、キーからかなり長いエスケープシーケンスを取得するいくつかの状況に直面することができます。例えば、

  • パターンを使用して、modifyOtherKeysキーボードの(ほとんどの)キーにエスケープシーケンスを割り当てます。
  • translations「すべての」文字シーケンスを送信できるリソースの使用
  • このDECUDK関数を使用して、アプリケーションで定義された文字列(16進数シーケンス)を送信します。

他の端末(OSX Terminal.appやiTerm2など)もユーザー設定可能な文字列を送信できます。この観点から見ると、キーが送信するバイト数には明確に定義された制限はありません。

一方、コンポーズはより明確に定義されています。結果は、与えられたエンコーディングの文字(または複数の文字?)です。文字が1つしかないとします。最大値基準UTF-8でエンコードされた文字の長さは4バイトです。時できるユーザーが設定したキーがこのデータを送信するのを見ると、ほとんどの場合(互換性と規則のため)、2つ(エスケープシーケンスとエンコードされた文字)が混在していることがわかりません。

追加資料:

関連情報