Frame della GUI
Nei frame della GUI (sia X11, Windows, OSX, ...), Emacs legge il Tabtasto come tab
tasto funzione. Tuttavia, poiché il Tabtasto sui terminali tradizionalmente invia il carattere ^I
( Control + I), Emacs traduce il tab
tasto funzione nel carattere Control + I (carattere 9), che viene visualizzato come TAB
. Questa traduzione viene effettuata tramite function-key-map
.
Una traduzione simile avviene con alcuni altri tasti funzione. ( Backspacee Deletesono un caso spinoso di cui non parlerò in dettaglio qui.)
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 si desidera separare Tabda Ctrl+ del Itutto, rimuovere l'associazione da function-key-map
:
(define-key function-key-map [tab] nil)
Tuttavia, ciò non è molto utile, poiché le voci in function-key-map
vengono sovrascritte dai collegamenti nelle mappe dei tasti specifiche della modalità o nella mappa globale. Quindi, se vuoi definire un'associazione diversa per tab
, fallo (in Elisp, non in modo interattivo, perché il prompt di lettura della chiave applica la function-key-map
traduzione in modo da finire con la rilegatura TAB
e non tab
):
(global-set-key [tab] '…)
(define-key some-mode-map [tab] '…)
Tutte le modalità standard che modificano l'azione della Tabchiave lo fanno modificando la TAB
chiave, che è un soprannome per il C-i
carattere generato dalla combinazione di tasti Ctrl+ I. Se desideri che i binding standard si applichino tab
piuttosto che C-i
, lascia function-key-map
e modifichi da solo le mappe dei tasti e invece reindirizza Ctrl+ Ia una chiave diversa.
(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] '…)
Ora Emacs riporterà Ctrl+ Icome " <control-i>
(tradotto da TAB
)". Questo non è carino, ma è inevitabile: la bella stampa del personaggio 9 così come TAB
è incorporata nel codice sorgente di Emacs.
Telai terminali
Nei terminali, il problema è più difficile e spesso impossibile. I terminali non trasmettono chiavi, trasmettono caratteri (più precisamente, infatti, trasmettono byte). La Tabchiave viene trasmessa come carattere di tabulazione, ovvero Control + I, uguale a ciò che genera la combinazione di tasti Ctrl+ I. I tasti funzione che non hanno caratteri corrispondenti (come i tasti cursore) vengono trasmessi come sequenze di escape, ovvero sequenze di caratteri che iniziano con ESC
= Control + [(motivo per cui Emacs definisce escapeun tasto prefisso - ESC
deve essere un prefisso). Vedi Come funzionano l'input da tastiera e l'output di testo? per più sfondo.
Esistono alcuni terminali che possono essere configurati per inviare sequenze di tasti diversi per i tasti funzione, ma non molti. Sia libtermkey / libtickit di LeoNerd che xterm di Thomas Dickey (dalla versione 216) supportano questo. In Xterm, la funzione è facoltativa e attivata tramite la modifyOtherKeys
risorsa. Tuttavia, non conosco alcun emulatore di terminale popolare diverso da xterm che supporti questo, in particolare i numerosi emulatori basati su libvte . Alcuni emulatori di terminale ti consentono di farlo manualmente attraverso una corrispondenza definita dall'utente dai tasti principali per sfuggire alle sequenze.
Questo meccanismo consente di distinguere molte combinazioni di tasti, non solo tab / Ci, return / Cm e escape / C- [. Vedere Problemi con le combinazioni di tasti quando si utilizza il terminale per una descrizione più dettagliata.
La funzione xterm di base è supportata da Emacs 24.4. Tuttavia i fondamentali (in particolare Tab, Return, Escape, Backspace) ancora inviare i caratteri di controllo tradizionali, perché è quello che si aspettano applicazioni. C'è una modalità in cui Ctrl+ letterinvia una sequenza di escape invece del carattere di controllo. Quindi, per distinguere i tasti funzione dalle Ctrlcombinazioni di Emacs 24.4, modifica il suo supporto per modifyOtherKeys
utilizzare questa modalità impostando la risorsa su 2 anziché 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))