GUI-Frames
In GUI-Frames (ob X11, Windows, OSX, ...) liest Emacs die TabTaste als tabFunktionstaste. Da die TabTaste auf den Terminals traditionell das Zeichen ^I( Strg + I) sendet , übersetzt Emacs die tabFunktionstaste in das Zeichen Strg + I (Zeichen 9), das als angezeigt wird TAB. Diese Übersetzung erfolgt über function-key-map.
Eine ähnliche Übersetzung erfolgt mit einigen anderen Funktionstasten. ( BackspaceUnd Deletees handelt sich um einen heiklen Fall, auf den ich hier nicht näher eingehen werde.)
Function key Translated to character Notes
Number Name Decomposition
backspace 127 DEL Ctrl+? May be translated to C-h instead
tab 9 TAB Ctrl+I
linefeed 10 LFD Ctrl+J Few keyboards have this key
return 13 RET Ctrl+M
escape 27 ESC Ctrl+[
Wenn Sie sich Tabvon Ctrl+ trennen möchten I, entfernen Sie die Bindung von function-key-map:
(define-key function-key-map [tab] nil)
Dies ist jedoch nicht sehr nützlich, da Einträge in function-key-mapdurch Bindungen in modusspezifischen Keymaps oder in der globalen Zuordnung überschrieben werden. Wenn Sie also eine andere Bindung definieren möchten tab, tun Sie dies einfach (in Elisp, nicht interaktiv, da die Eingabeaufforderung zum Lesen des Schlüssels die function-key-mapÜbersetzung anwendet, sodass Sie erneut binden TABund nicht tab):
(global-set-key [tab] '…)
(define-key some-mode-map [tab] '…)
Alle Standardmodi, die die Aktion der TabTaste ändern, ändern dazu die Taste. Dies TABist ein Kurzname für das C-idurch die Tastenkombination Ctrl+ erzeugte Zeichen I. Wenn Sie Standard - Bindings anwenden möchten tabals vielmehr C-i, verlassen function-key-mapund Modus keymaps allein und stattdessen Umleitung Ctrl+ Izu einem anderen Schlüssel.
(define-key input-decode-map [(control ?i)] [control-i])
(define-key input-decode-map [(control ?I)] [(shift control-i)])
(define-key some-mode-map [control-i] '…)
Jetzt wird Emacs Ctrl+ Ials " <control-i>(übersetzt von TAB)" melden . Das ist nicht schön, aber es ist unvermeidlich: das schöne Drucken von Zeichen 9, wie TABes im Emacs-Quellcode enthalten ist.
Terminalrahmen
In Terminal-Frames ist das Problem schwerer und oft unmöglich. Terminals übertragen keine Schlüssel, sie übertragen Zeichen (genauer gesagt, sie übertragen Bytes). Die TabTaste wird als Tabulatorzeichen übertragen - das ist Strg + I, genau wie das, was die Tastenkombination Ctrl+ Ierzeugt. Funktionstasten, die kein entsprechendes Zeichen enthalten (z. B. Cursortasten), werden als Escape-Sequenzen übertragen, dh Sequenzen von Zeichen, die mit ESC= Strg + [beginnen (weshalb Emacs escapeals Präfix-Taste definiert - ESCmuss ein Präfix sein). Siehe Wie funktionieren Tastatureingaben und Textausgaben? für mehr hintergrund.
Es gibt einige Terminals, die so konfiguriert werden können, dass sie unterschiedliche Tastenfolgen für Funktionstasten senden, aber nicht viele. Dies wird sowohl von LeoNerds libtermkey / libtickit als auch von Thomas Dickeys xterm (seit Version 216) unterstützt. In Xterm ist die Funktion optional und wird über die modifyOtherKeysRessource aktiviert . Ich kenne jedoch keinen anderen beliebten Terminal-Emulator als xterm, der dies unterstützt, insbesondere die vielen Emulatoren, die auf libvte basieren . Bei einigen Terminal-Emulatoren können Sie dies manuell über eine benutzerdefinierte Entsprechung von Tastenkombinationen zu Escape-Sequenzen ausführen.
Mit diesem Mechanismus können viele Tastenkombinationen unterschieden werden, nicht nur tab / Ci, return / Cm und escape / C- [. Eine ausführlichere Beschreibung finden Sie unter Probleme mit der Tastaturbelegung bei Verwendung des Terminals .
Die grundlegende xterm-Funktion wird seit Emacs 24.4 unterstützt. Allerdings sind die Grundlagen (insbesondere Tab, Return, Escape, Backspace) nach wie vor die traditionellen Steuerzeichen senden, weil das, was Anwendungen erwarten. Es gibt einen Modus, in dem Ctrl+ letteranstelle des Steuerzeichens eine Escape-Sequenz sendet. CtrlUm die Funktionstasten von den Kombinationen in Emacs 24.4 zu unterscheiden, ändern Sie die Unterstützung für modifyOtherKeysdiesen Modus, indem Sie die Ressource auf 2 statt auf 1 setzen.
;; xterm with the resource ?.VT100.modifyOtherKeys: 2
;; GNU Emacs >=24.4 sets xterm in this mode and define
;; some of the escape sequences but not all of them.
(defun character-apply-modifiers (c &rest modifiers)
"Apply modifiers to the character C.
MODIFIERS must be a list of symbols amongst (meta control shift).
Return an event vector."
(if (memq 'control modifiers) (setq c (if (or (and (<= ?@ c) (<= c ?_))
(and (<= ?a c) (<= c ?z)))
(logand c ?\x1f)
(logior (lsh 1 26) c))))
(if (memq 'meta modifiers) (setq c (logior (lsh 1 27) c)))
(if (memq 'shift modifiers) (setq c (logior (lsh 1 25) c)))
(vector c))
(defun my-eval-after-load-xterm ()
(when (and (boundp 'xterm-extra-capabilities) (boundp 'xterm-function-map))
;; Override the standard definition to set modifyOtherKeys to 2 instead of 1
(defun xterm-turn-on-modify-other-keys ()
"Turn the modifyOtherKeys feature of xterm back on."
(let ((terminal (frame-terminal)))
(when (and (terminal-live-p terminal)
(memq terminal xterm-modify-other-keys-terminal-list))
(send-string-to-terminal "\e[>4;2m" terminal))))
(let ((c 32))
(while (<= c 126)
(mapc (lambda (x)
(define-key xterm-function-map (format (car x) c)
(apply 'character-apply-modifiers c (cdr x))))
'(;; with ?.VT100.formatOtherKeys: 0
("\e\[27;3;%d~" meta)
("\e\[27;5;%d~" control)
("\e\[27;6;%d~" control shift)
("\e\[27;7;%d~" control meta)
("\e\[27;8;%d~" control meta shift)
;; with ?.VT100.formatOtherKeys: 1
("\e\[%d;3~" meta)
("\e\[%d;5~" control)
("\e\[%d;6~" control shift)
("\e\[%d;7~" control meta)
("\e\[%d;8~" control meta shift)))
(setq c (1+ c)))))
(define-key xterm-function-map "")
t)
(eval-after-load "xterm" '(my-eval-after-load-xterm))