Non puoi davvero cambiare l' C-[associazione a mappe a livello di utente, come faresti con global-set-key
. Tuttavia, è possibile modificarlo come evento da tastiera prima che raggiunga quelle mappe dei tasti. Puoi dire per esempio:
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
e poi [control-bracketleft]
usalo nelle tue keymap. Abbastanza semplice no?
Scene extra
Sfortunatamente, non è così semplice e questa soluzione richiede alcuni aggiustamenti, che sembreranno molto dolorosi. Sei stato avvisato. Ma vediamo innanzitutto perché le mappe a livello di utente non possono rispondere alla domanda. Di seguito, mi riferisco al manuale di Emacs Lisp per emacs 26.1 quando dico "vedere qualcosa" senza più precisione.
C-[viene interpretato molto presto come il carattere di controllo ASCII ESC
(vedi 21.7.1 - Eventi tastiera ). Questo codice viene distribuito in tutte le altre posizioni come prefisso per sequenze più lunghe. C'è una ragione per questo: in ESC
realtà è il meta prefisso (vedi meta-prefix-char
), e tutti i binding che leggono
M-qualcosa si tradurranno in una sequenza che inizia con ESC
. Pertanto, cambiare la mappa globale non sarà sufficiente: devi prima cambiare meta-prefix-char
, quindi rimappare ESC
al tuo nuovo meta-prefix-char
in ogni mappa che usi M-prima di poter mappare in sicurezza C-[.
OK allora, ovviamente: usiamo input-decode-map
. Esistono un paio di mappe simili che potremmo essere tentati di usare (vedere le sezioni 21.8.3 e 22.14), ma atteniamoci a questa. E bene ... questo funziona! Hai finito, vero?
In realtà no, la storia non finisce qui. Funziona ... fintanto che stai usando un sistema a finestre. Se per sfortuna sei imprigionato nella console di Linux in uno stato di emergenza, ti rendi conto di quanto sia drammatica la situazione: i tasti freccia Homee, ovviamente M-, i collegamenti, sono tutti spazzatura. Perché? Perché quando dice il terminale ESC
(cosa che fa quando si digita C-[), significa davvero ESC
, e inizia una sequenza dello stesso tipo che usa per trasmettere caratteri non ASCII.
Osservando il disastro, potresti considerare saggio proteggere la input-decode-map
modifica di cui sopra in modo tale che si attivi solo nel caso in cui un sistema a finestre stia controllando la tastiera:
(let ((frame (framep (selected-frame))))
(or (eq t frame)
(eq 'pc frame)
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
)))
I terminali quindi funzionano come prima.
Ora, possiamo occuparci dei C-[terminali? In realtà, sì, possiamo, sia sulla console Linux che sugli altri emulatori di terminali con cui posso giocare. Ma questo rende la storia piuttosto lunga, poiché nuovi personaggi entrano nella scena. Perché non è più solo emacs: il terminale ha ora il ruolo centrale.
Diamo un'occhiata a ciò che la console linux ha da dire. Digita C-vprima di un tasto per ascoltarlo chiaramente. C-[è ESC
; così è Esc. La freccia su suona come ESC [ A
, mentre lo M-aè
ESC A
. Hmm ... Sembra che questa meta-circonvoluzione in emacs non sia vero? Comunque.
A meno che non siamo pronti a giocare alcuni trucchi in base al tempo trascorso tra gli eventi del personaggio (che tra l'altro non si distinguerà
Escda C-[), sembra che non abbiamo altra scelta che dire alla console ciò che in realtà non intendiamo ESC
quando digitiamo C-[. Inoltre, sembra abbastanza presto che C-[non sia l'unico problema con i codici terminali di serie: i modificatori vengono spesso cancellati dalle informazioni trasmesse. Dobbiamo personalizzare il terminale per lo stesso motivo per cui personalizziamo emacs: sarebbe molto più pratico se lo facessimo.
A questo punto, avrai il coraggio di dare uno sguardo approfondito agli occhi della documentazione del tuo terminale: pagine man loadkeys(1)
per la console linux, per xterm
xterm(1)
nella sezione Associazioni chiave personalizzate e tutto ciò che non so per altri terminali. In KDE konsole
, puoi definire traduzioni personalizzate in Impostazioni / Modifica profilo corrente ...
quindi Tastiera . Ecco un estratto da ~/.local/share/konsole/Test.keytab
dopo aver giocato con quest'ultima finestra di dialogo:
key [+Ctrl+AnyModifier : "\EO*["
Una volta che avete l'invio del terminale ESC O 5 [
per
C-[(come nella configurazione di cui sopra), si può tornare a emacs. Ovviamente, non hai ancora finito.
Per indicare a emacs quale dialetto utilizza un determinato terminale, è possibile regolare input-decode-map
. Sì, questo è casualmente quello che abbiamo modificato all'inizio di questa storia, e questo è quello che
term/xterm.el
tocca quando è coinvolto xterm. Un buon posto per la regolazione è tty-setup-hook
(vedere la sezione 40.1.3):
(add-hook 'tty-setup-hook
(lambda ()
(let ((term (getenv "TERM")))
(cond
(;; xterm-function-map not in doc, but in term/xterm.el
(boundp 'xterm-function-map)
(map-my-term-codes xterm-function-map))
((equal term "linux")
(map-my-term-codes input-decode-map))
)
)))
Ricorda che questo hook funziona solo se ti trovi in un terminale. Pertanto, non è possibile inserire qui il codice per l'inizializzazione del sistema di finestre. Ecco la funzione di traduzione da sola:
(defun map-my-term-codes (map)
(define-key map (kbd "M-O 5 [")
[control-bracketleft])
)
E poi puoi riposarti: è la fine del viaggio. Naturalmente, se non ti interessano i terminali, è veloce poiché salterai tutta la parte dolorosa. Ma riconoscerai che è anche piuttosto incompleto.
Due note finali:
Ho scelto ESC O 5 [
di codificare C-[. Questo è solo un esempio: non pretendo che sia una buona scelta. Solo la 5
parte, il che significa C-, sembra obbedire a una sorta di convenzione stabilita
la configurazione della console linux lascia un cattivo gusto: non sembra possibile fare il binding senza usare un simbolo intermedio esistente , e quelli di cui avrei bisogno
non esistono . Uso i simboli nell'intervallo F21- F246come nella maggior parte degli esempi di Internet, ma non è molto soddisfacente. Va bene per alcuni collegamenti non correlati, ma non servirà uno schema sistematico.
modificare
- Ho completato questo con il Esccaso - che ha una sua personalità - in un altro post: Come rimuovere i collegamenti alla chiave del prefisso ESC
ecco un frammento di una configurazione con cui nutrirsi loadkeys
. L'ho inserito in /root/custom.kmap e lo carico quando necessario (cosa rara). La mia configurazione attuale mappa anche le frecce e le diverse combinazioni di modificatori, ma è piuttosto lunga, la scelta dei simboli e delle sequenze è discutibile e non sono sicuro che i codici chiave per la mia tastiera corrisponderanno ai tuoi. Quindi manteniamolo al suo giusto livello: questo non è altro che un'illustrazione.
keymaps 0-127
# http://tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html
# web+man:keymaps
# web+man:loadkeys
# escape
keycode 1 = F100
alt keycode 1 = Escape # keep the Escape behavior somewhere
# keycode 26 = bracketleft
control keycode 26 = F115 # Control_bracketleft does not exist
string F100 = "\033OO" # map this to [escape] in map-my-term-codes
string F115 = "\033O5["