GUI-Frames
In GUI-Frames (ob X11, Windows, OSX, ...) liest Emacs die TabTaste als tab
Funktionstaste. Da die TabTaste auf den Terminals traditionell das Zeichen ^I
( Strg + I) sendet , übersetzt Emacs die tab
Funktionstaste 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-map
durch 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 TAB
und 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 TAB
ist ein Kurzname für das C-i
durch die Tastenkombination Ctrl+ erzeugte Zeichen I. Wenn Sie Standard - Bindings anwenden möchten tab
als vielmehr C-i
, verlassen function-key-map
und 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 TAB
es 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 - ESC
muss 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 modifyOtherKeys
Ressource 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 modifyOtherKeys
diesen 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))