Quadros da GUI
Nos quadros da GUI (seja X11, Windows, OSX,…), o Emacs lê a Tabchave como a tab
tecla de função. No entanto, como a Tabtecla nos terminais envia tradicionalmente o caractere ^I
( Control + I), o Emacs converte a tab
tecla de função no caractere Control + I (caractere 9), que é exibido como TAB
. Esta tradução é feita via function-key-map
.
Uma tradução semelhante ocorre com algumas outras teclas de função. ( Backspacee Deleteé um caso espinhoso que não discutirei em detalhes aqui.)
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+[
Se você deseja separar Taba partir Ctrl+ Icompletamente, remover a ligação de function-key-map
:
(define-key function-key-map [tab] nil)
No entanto, isso não é muito útil, porque as entradas em function-key-map
são substituídas por ligações em mapas de teclas específicos de modo ou no mapa global. Portanto, se você deseja definir uma ligação diferente tab
, basta fazê-lo (no Elisp, não de maneira interativa, porque o prompt de leitura de chave aplica a function-key-map
tradução, para que você acabe religando TAB
e não tab
):
(global-set-key [tab] '…)
(define-key some-mode-map [tab] '…)
Todos os modos padrão que modificam a ação da Tabchave fazem isso modificando a TAB
chave, que é um apelido para o C-i
caractere gerado pela combinação de teclas Ctrl+ I. Se você deseja que as ligações padrão sejam aplicadas em tab
vez de C-i
, deixe function-key-map
e modifique os mapas de teclas sozinhos e, em vez disso, redirecione Ctrl+ Ipara uma chave 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] '…)
Agora o Emacs reportará Ctrl+ Icomo " <control-i>
(traduzido de TAB
)". Isso não é bonito, mas é inevitável: a bonita impressão do personagem 9, como TAB
está embutida no código-fonte do Emacs.
Quadros de terminais
Nos quadros de terminais, o problema é mais difícil e geralmente impossível. Os terminais não transmitem chaves, eles transmitem caracteres (mais precisamente, eles transmitem bytes). A Tabtecla é transmitida como o caractere de tabulação - que é Control + I, igual ao que a combinação de teclas Ctrl+ Igera. As teclas de função que não possuem caracteres correspondentes (como teclas de cursor) são transmitidas como seqüências de escape, ou seja, sequências de caracteres começando com ESC
= Control + [(é por isso que o Emacs define escapecomo uma tecla de prefixo - ESC
deve ser um prefixo). Consulte Como funcionam a entrada do teclado e a saída de texto? para mais informações.
Existem alguns terminais que podem ser configurados para enviar sequências de teclas diferentes para teclas de função, mas não muitas. Ambos de LeoNerd libtermkey / libtickit e xterm de Thomas Dickey (desde a versão 216) suporta isto. No Xterm, o recurso é opcional e ativado por meio do modifyOtherKeys
recurso. No entanto, não conheço outro emulador de terminal popular que não seja o xterm que suporte isso, em particular os muitos emuladores criados com libvte . Alguns emuladores de terminal permitem fazer isso manualmente por meio de uma correspondência definida pelo usuário, dos acordes de teclas, para escapar das seqüências.
Este mecanismo permite distinguir muitas combinações de teclas, não apenas tab / Ci, return / Cm e escape / C- [. Consulte Problemas com atalhos de teclas ao usar o terminal para obter uma descrição mais detalhada.
O recurso básico do xterm é suportado desde o Emacs 24.4. No entanto, os fundamentos (em particular Tab, Return, Escape, Backspace) ainda enviar os caracteres de controle tradicionais, porque é isso que as aplicações esperar. Existe um modo em que Ctrl+ letterenvia uma sequência de escape em vez do caractere de controle. Portanto, para distinguir as teclas de função das Ctrlcombinações no Emacs 24.4, modifique seu suporte para modifyOtherKeys
usar esse modo, configurando o recurso para 2 em vez 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))