ターミナルで実行されている Emacs が Ctrl+; と ";" を区別できないのはなぜですか?

ターミナルで実行されている Emacs が Ctrl+; と ";" を区別できないのはなぜですか?

この疑問は私のemacsベータ版に関する以前の質問C-;簡単に言うと、ターミナルで Emacs 関数にバインドしたいのですが、このキーが Emacs に到達する前に何かがそれをキャプチャしているようです。Emacs は私が を押したと認識します;

明らかに疑わしいのはターミナル エミュレータですが、それらの多く (xterm、gnome-terminal、terminator、terminology) をチェックしましたが、どれも機能しません。おそらくウィンドウ マネージャは除外できます。Emacs の GUI バージョンでは、キーはC-;正常に機能するからです。また、bash と zsh という 2 つの異なるシェルも試しましたが、やはり成功しませんでした。

他に何を試すことができますか?

答え1

おそらくあなたの混乱は、実際の端末を使ったことがないために生じているのでしょう。本格的なコンピュータが数台の縦型冷蔵庫ほどの大きさだった頃、ターミナルシリアル ケーブルを介して文字と記号のみを使用して中央コンピュータと通信します。文字は、ASCII や EBCDIC などの標準化された文字セットの一部ですが、通常は ASCII です。ASCII には 33 個の制御文字があり、端末オペレータは特殊キー (DEL など) を押すか、Ctrl キーを押しながら別のキーを押して制御文字を送信します。中央コンピュータは結果の制御文字のみを認識し、文字を生成するためにどのキーが押されたかを認識しませんでした。

xterm などの端末エミュレーション プログラムは、この動作を模倣します。端末エミュレーターは、33 個の ASCII 制御文字すべてを送信する方法を提供し、Emacs は、送信された文字を受信します。しかし、Emacs は上記の説明の中央コンピュータのようなものです。つまり、端末エミュレーターで実行したときに、実際にどのキーが押されたかを知る方法がありません。したがって、Ctrl キーとセミコロンを押しても、端末エミュレーション プログラムがそれらのキー押下を何らかの ASCII 文字にマップしていない限り、Emacs は何かが入力されたことを認識しません。

端末エミュレータは通常、制御文字を生成するために次のマッピングを使用します :

キー押下 ASCII
--------------------
エスケープ27
削除 127
バックスペース8
Ctrl+スペース 0
Ctrl+@ 0
Ctrl+A 1
Ctrl+B 2 キー
Ctrl+C 3 クリック
等...
Ctrl+X 24
Ctrl+Y 25
Ctrl+Z 26
Ctrl+[ 27
Ctrl+\ 28
Ctrl+] 29
Ctrl+^ 30 クリック
Ctrl+_ 31 クリック

CTRL+; はリストに表示されないことに注意してください。端末は通常、割り当てられた印刷可能な文字を送信するだけです。CTRL+の場合制御文字にマップされていません。したがって、ターミナル エミュレータが ; だけを送信することで伝えているのは、CTRL+; を押したときに何をすべきかわからないということです。

これらはすべて、端末または端末エミュレーション プログラムを使用している場合にのみ適用されます。Emacs を何らかのウィンドウ システムでネイティブ アプリケーションとして実行している場合、Emacs は文字だけでなくキーストローク イベントにも完全にアクセスできます。そのため、Emacs は CTRL キーとセミコロンが同時に押されたことを認識し、そのキーストローク ペアにアクションを割り当てることができます。

端末には、制御文字を含む文字列を生成するファンクション キーや矢印キーが付いていることがよくあります。これらの文字列は通常、ASCII コード 27 (ESCAPE) で始まります。

答え2

端末はキーではなく文字 (より正確にはバイト) を送信します。キーまたはCtrl+のようなキーコードを押すと;、この情報はバイトのシーケンスにエンコードされる必要があります。AまたはShift+Aまたは のような文字を表すキーコードはÀ、その文字として送信されます: aAà(最後の文字は、端末の文字エンコードに応じて 1 バイトまたは 2 バイトになります)。

ファンクションキーを含むキーコードには対応する文字がないので、エスケープシーケンスとして送信されます。エスケープ文字(\eEmacs文字列では、^[バッファに文字どおりに入力された場合はシアン色で表示されます)で始まるバイトシーケンスです。いくつかのファンクションキーには対応するバイトがあり、制御文字

キーコードCtrl+;には標準のエスケープ シーケンスがないため、ほとんどのターミナル エミュレーターは文字 を生成します。これにより、修飾子が押された;という情報が失われます。Ctrl

Ctrl+のバインディングを定義するには;、異なるエスケープシーケンスを送信するようにターミナルエミュレータを設定する必要があります。Gnomeターミナルではこれができないと思います(Gnomeはほとんど設定できません)。Xtermでは可能です。すべてのキーの組み合わせを処理できる Linux ターミナルはありますか?手順についてはこちらをご覧ください。

ターミナルで実行するシェルは関係ありません。GUI (X11) は、単なる文字列としてではなく、キーと修飾子をエンコードした形式で入力イベントを送信するため、GUI Emacs では問題はありません。

見るキーボード入力とテキスト出力はどのように機能しますか?キーボードからアプリケーションへの入力がどのように行われるかについての詳細な背景情報。

関連情報