Marcos GUI
En los marcos de la GUI (ya sea X11, Windows, OSX, ...), Emacs lee la Tabtecla como la tab
tecla de función. Sin embargo, debido a que la Tabtecla en los terminales envía tradicionalmente el carácter ^I
( Control + I), Emacs traduce la tab
tecla de función al carácter Control + I (carácter 9), que se muestra como TAB
. Esta traducción se realiza a través de function-key-map
.
Una traducción similar ocurre con algunas otras teclas de función. ( Backspacey Deletees un caso espinoso que no discutiré en detalle aquí).
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+[
Si desea separar Tabde Ctrl+ por Icompleto, elimine el enlace de function-key-map
:
(define-key function-key-map [tab] nil)
Sin embargo, esto no es muy útil, ya que las entradas function-key-map
se anulan mediante enlaces en mapas de teclas específicos del modo o en el mapa global. Entonces, si desea definir un enlace diferente para tab
, simplemente hágalo (en Elisp, no de forma interactiva, porque el indicador de lectura clave aplica la function-key-map
traducción para que termine volviendo a vincular TAB
y no tab
):
(global-set-key [tab] '…)
(define-key some-mode-map [tab] '…)
Todos los modos estándar que modifican la acción de la Tabtecla lo hacen modificando la TAB
tecla, que es un apodo para el C-i
carácter generado por la combinación de teclas Ctrl+ I. Si desea que se apliquen enlaces estándar en tab
lugar de C-i
, deje function-key-map
y modele mapas de teclas solos y, en su lugar, redirija Ctrl+ Ia una tecla diferente.
(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] '…)
Ahora Emacs informará Ctrl+ Icomo " <control-i>
(traducido de TAB
)". Esto no es bonito, pero es inevitable: la bonita impresión del carácter 9 tal como TAB
está integrado en el código fuente de Emacs.
Marcos terminales
En marcos de terminales, el problema es más difícil y a menudo imposible. Los terminales no transmiten claves, transmiten caracteres (más precisamente, de hecho, transmiten bytes). La Tabclave se transmite como el carácter de tabulación, que es Control + I, igual que lo que genera la combinación de teclas Ctrl+ I. Las teclas de función que no tienen un carácter correspondiente (como las teclas del cursor) se transmiten como secuencias de escape, es decir, secuencias de caracteres que comienzan con ESC
= Control + [(por lo que Emacs define escapecomo una tecla de prefijo, ESC
tiene que ser un prefijo). Consulte ¿Cómo funcionan la entrada del teclado y la salida de texto? para más antecedentes
Hay algunos terminales que se pueden configurar para enviar diferentes secuencias de teclas para las teclas de función, pero no muchos. Tanto libtermkey / libtickit de LeoNerd como xterm de Thomas Dickey (desde la versión 216) lo respaldan. En Xterm, la función es opcional y se activa a través del modifyOtherKeys
recurso. Sin embargo, no conozco ningún emulador de terminal popular que no sea xterm que admita esto, en particular los muchos emuladores creados en libvte . Algunos emuladores de terminal le permiten hacer esto manualmente a través de una correspondencia definida por el usuario desde los teclados para escapar de las secuencias.
Este mecanismo permite distinguir muchas combinaciones de teclas, no solo tab / Ci, return / Cm y escape / C- [. Consulte Problemas con las combinaciones de teclas al usar la terminal para obtener una descripción más detallada.
La función xterm básica es compatible desde Emacs 24.4. Sin embargo, los fundamentos (en particular Tab, Return, Escape, Backspace) siguen enviando los caracteres de control tradicionales, porque eso es lo que esperan que las aplicaciones. Hay un modo donde Ctrl+ letterenvía una secuencia de escape en lugar del carácter de control. Entonces, para distinguir las teclas de función de las Ctrlcombinaciones en Emacs 24.4, modifique su soporte para modifyOtherKeys
usar este modo estableciendo el recurso en 2 en lugar de 1.
;; 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))