為什麼在終端機中運行的 Emacs 無法區分 Ctrl+;從 ”;”?

為什麼在終端機中運行的 Emacs 無法區分 Ctrl+;從 ”;”?

這個問題源自於我的上一個關於 emacs beta 的問題。簡而言之,我想綁定C-;到終端中的 Emacs 函數,但似乎有東西在到達 Emacs 之前捕獲了此鍵:Emacs 認為我按下了;

明顯的嫌疑是終端模擬器,但我檢查了其中的許多(xterm、gnome-terminal、terminator、terminology),但它們都不起作用。我很可能可以排除視窗管理器,因為在 Emacs 的 GUI 版本中,該鍵C-;運作得很好。我還嘗試了兩種不同的 shell:bash 和 zsh,但再次沒有成功。

我還能嘗試什麼?

答案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
ETC...
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+這樣的鍵和弦時;,該資訊必須編碼為位元組序列。表示字元的按鍵和弦,如AShift+AÀ,作為該字元發送:a, A, à(最後一個是一個或兩個位元組,取決於終端的字元編碼)。

涉及功能鍵的按鍵沒有對應的字符,因此它們作為轉義序列發送:以轉義字符開頭的字節序列(\e在 Emacs 字串中,^[如果在緩衝區中逐字輸入,則顯示為青色)。一些功能鍵有相應的字節,它們是控製字元

鍵和鍵Ctrl+;沒有標準轉義序列,因此大多數終端模擬器都會產生字元;。這會遺失Ctrl按下修改器的資訊。

為了定義Ctrl+的綁定;,您需要配置終端模擬器以傳送不同的轉義序列。我不認為你可以用 Gnome 終端來做到這一點(Gnome 很少是可配置的)。您可以使用 Xterm 來完成。看有沒有可以處理所有組合鍵的 Linux 終端機?以獲得指示。

不涉及您可能在終端機中運行的 shell。 GUI Emacs 沒有問題,因為 GUI (X11) 以編碼鍵和修飾符的形式傳輸輸入事件,而不僅僅是字元序列。

鍵盤輸入和文字輸出如何運作?有關輸入如何從鍵盤傳輸到應用程式的更多詳細背景資訊。

相關內容