Diese Frage entstand aus meinervorherige Frage zur Emacs-Beta. Kurz gesagt, ich möchte eine Bindung C-;
an eine Emacs-Funktion in einem Terminal herstellen, aber es scheint, dass etwas diese Taste abfängt, bevor sie Emacs erreicht: Emacs denkt, ich hätte gedrückt ;
.
Der offensichtliche Verdächtige ist der Terminalemulator, aber ich habe viele davon überprüft (xterm, gnome-terminal, terminator, terminology) und keiner davon funktioniert. Höchstwahrscheinlich kann ich den Fenstermanager ausschließen, da die Taste in der GUI-Version von Emacs C-;
einwandfrei funktioniert. Ich habe auch zwei verschiedene Shells ausprobiert: bash und zsh, aber auch hier ohne Erfolg.
Was kann ich sonst noch versuchen?
Antwort1
Vielleicht liegt Ihre Verwirrung daran, dass Sie noch nie ein echtes Terminal benutzt haben. Damals, als ernsthafte Computer die Größe mehrerer aufrecht stehender Kühlschränke hatten,Terminalkommunizierte mit einem Zentralrechner über ein serielles Kabel und verwendete dabei nur Zeichen und Buchstaben. Die Zeichen waren Teil eines standardisierten Zeichensatzes, z. B. ASCII oder EBCDIC, aber normalerweise ASCII. ASCII hat 33 Steuerzeichen und der Terminalbediener sendete sie, indem er eine spezielle Taste (z. B. ENTF) drückte oder indem er die STRG-Taste gedrückt hielt und eine andere Taste drückte. Der Zentralrechner sah nur das resultierende Steuerzeichen; er wusste nicht, welche Tasten gedrückt wurden, um das Zeichen zu erzeugen.
Ein Terminalemulationsprogramm wie xterm ahmt dieses Verhalten nach. Der Terminalemulator bietet eine Möglichkeit, alle 33 ASCII-Steuerzeichen zu senden, und Emacs empfängt diese Zeichen, wenn sie gesendet werden. Aber Emacs ist wie der Zentralcomputer in der obigen Beschreibung – er kann nicht wissen, welche Tasten tatsächlich gedrückt wurden, wenn Sie ihn unter einem Terminalemulator ausführen. Wenn Sie also STRG und Semikolon drücken, weiß Emacs nicht, dass etwas eingegeben wurde, es sei denn, das Terminalemulationsprogramm hat diese Tastendrücke einem ASCII-Zeichen zugeordnet.
Terminalemulatoren verwenden normalerweise die folgenden Zuordnungen, um Steuerzeichen † zu generieren :
Tastendruck ASCII -------------------- Flucht 27 LÖSCHEN 127 RÜCKTASTE 8 STRG+LEERTASTE 0 STRG+@ 0 STRG+A 1 STRG+B 2 STRG+C 3 usw... STRG+X 24 STRG+Y 25 STRG+Z 26 STRG+[ 27 STRG+\ 28 STRG+] 29 STRG+^ 30 STRG+_ 31
Beachten Sie, dass STRG+; in dieser Liste nicht erscheint. Terminals senden normalerweise nur das druckbare Zeichen, das zugewiesen istSchlüsselwenn STRG+Schlüsselist keinem Steuerzeichen zugeordnet. Ihr Terminalemulator sagt Ihnen also durch das Senden von ; nur, dass er nicht weiß, was zu tun ist, wenn Sie STRG+; drücken.
Dies alles gilt nur, wenn Sie ein Terminal oder ein Terminalemulationsprogramm verwenden. Wenn Sie Emacs als native Anwendung unter einem Windows-System ausführen, hat Emacs vollen Zugriff auf die Tastenanschlagereignisse und nicht nur auf Zeichen. Emacs kann also erkennen, dass Sie STRG und Semikolon gleichzeitig gedrückt haben, und Ihnen erlauben, diesem Tastenanschlagpaar eine Aktion zuzuweisen.
† Terminals verfügen häufig über Funktionstasten und Pfeiltasten, die auch Zeichenfolgen generieren, die Steuerzeichen enthalten. Diese Sequenzen beginnen normalerweise mit dem ASCII-Code 27 (ESCAPE).
Antwort2
Terminals übertragen Zeichen (genauer: Bytes), keine Tasten. Wenn Sie eine Taste oder ein Tastenkürzel wie Ctrl+ drücken ;, muss diese Information in eine Bytefolge kodiert werden. Tastenkürzel, die ein Zeichen darstellen, wie Aoder Shift+ Aoder À, werden als dieses Zeichen gesendet: a
, A
, à
(das letzte ist ein oder zwei Bytes lang, abhängig von der Zeichenkodierung des Terminals).
Tastenkürzel mit Funktionstasten haben kein entsprechendes Zeichen, daher werden sie als Escape-Sequenzen gesendet: eine Folge von Bytes, die mit dem Escape-Zeichen beginnen ( \e
in einem Emacs-String, erscheint in Cyan, ^[
wenn es wörtlich in einen Puffer eingegeben wird). Einige Funktionstasten haben entsprechende Bytes, dieSteuerzeichen.
Für die Taste Ctrl+ ;gibt es keine standardmäßige Escape-Sequenz, daher generieren die meisten Terminalemulatoren das Zeichen ;
. Dabei geht die Information verloren, dass der CtrlModifikator gedrückt wurde.
Um eine Bindung für Ctrl+ zu definieren ;, müssen Sie Ihren Terminalemulator so konfigurieren, dass er eine andere Escape-Sequenz sendet. Ich glaube nicht, dass Sie dies mit dem Gnome-Terminal tun können (Gnome ist selten konfigurierbar). Sie können es mit Xterm tun. SieheGibt es Linux-Terminals, die alle Tastenkombinationen verarbeiten können?für Anweisungen.
Die Shell, die Sie möglicherweise im Terminal ausführen, ist nicht betroffen. Ein GUI-Emacs hat kein Problem, da die GUI (X11) Eingabeereignisse in einer Form überträgt, die Tasten und Modifikatoren kodiert, und nicht als bloße Zeichenfolge.
SehenWie funktionieren Tastatureingabe und Textausgabe?für ausführlichere Hintergrundinformationen dazu, wie die Eingabe von Ihrer Tastatur an Ihre Anwendung gelangt.