Vous ne pouvez pas vraiment changer la C-[liaison au niveau des cartes utilisateur, comme vous le feriez avec global-set-key
. Cependant, vous pouvez le modifier en tant qu'événement clavier avant qu'il n'atteigne ces images clés. Vous pouvez dire par exemple:
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
puis utiliser [control-bracketleft]
dans vos keymaps. Assez simple n'est-ce pas?
Coupure du réalisateur
Malheureusement, ce n'est pas si simple, et cette solution nécessite quelques ajustements, qui sembleront très douloureux. Tu as été prévenu. Mais voyons d'abord pourquoi les cartes de niveau utilisateur ne peuvent pas répondre à la question. Dans ce qui suit, je me réfère au manuel Emacs Lisp pour emacs 26.1 quand je dis "voir quelque chose" sans plus de précision.
C-[est interprété très tôt comme le caractère de contrôle ASCII ESC
(voir 21.7.1 - Événements clavier ). Ce code est réparti dans tous les autres endroits comme préfixe pour les séquences plus longues. Il y a une raison à cela: ESC
est en fait le préfixe méta (voir meta-prefix-char
), et toutes les liaisons qui lisent
M-quelque chose se traduiront par une séquence commençant par ESC
. Ainsi, changer la carte globale ne sera pas suffisant: vous devez d'abord changer meta-prefix-char
, puis remapper ESC
sur votre nouvelle meta-prefix-char
carte dans chaque carte utilisée M-avant de pouvoir cartographier en toute sécurité C-[.
OK alors, bien sûr: utilisons input-decode-map
. Il y a quelques cartes similaires que nous pouvons être tentés d'utiliser (voir les sections 21.8.3 et 22.14), mais restons-en à celle-ci. Et bien ... ça marche! Vous avez terminé, n'est-ce pas?
En fait, non, l'histoire ne s'arrête pas là. Cela fonctionne ... tant que vous utilisez un système de fenêtre. Si, par malchance, vous êtes emprisonné dans la console Linux dans un état d'urgence, vous vous rendez compte à quel point la situation est devenue dramatique: les touches fléchées Home, et bien sûr les M-liaisons, sont toutes des ordures. Pourquoi? Parce que lorsque le terminal dit ESC
(ce qu'il fait lorsque vous tapez C-[), cela signifie vraiment ESC
et démarre une séquence du même type qu'il utilise pour transmettre des caractères non ASCII.
En observant la catastrophe, vous pouvez considérer qu'il est sage de protéger la input-decode-map
modification ci-dessus de telle sorte qu'elle ne s'active que dans le cas où un système de fenêtre contrôle le clavier:
(let ((frame (framep (selected-frame))))
(or (eq t frame)
(eq 'pc frame)
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
)))
Les terminaux fonctionnent alors comme avant.
Maintenant, pouvons-nous traiter C-[sur les terminaux? En fait, oui, nous pouvons, sur la console Linux ainsi que sur les autres émulateurs de terminaux avec lesquels je peux jouer. Mais cela rend l'histoire assez longue, car de nouveaux personnages entrent en scène. Car ce n'est plus seul emacs: le terminal a désormais le rôle central.
Écoutons ce que la console Linux a à dire. Tapez C-vdevant une touche pour l'entendre clairement. C-[est ESC
; il en est de même Esc. La flèche vers le haut ressemble à ESC [ A
, tandis que l' M-aest
ESC A
. Hmm ... On dirait que cette méta-circonvolutions clés dans emacs n'est-ce pas? En tous cas.
À moins que nous sommes prêts à jouer quelques tours en fonction du temps écoulé entre les événements de caractères (qui , par ailleurs ne distinguer
Escde C-[), il semble que nous avons pas d'autre choix que de dire la console ce que nous faisons pas dire ESC
quand on tape C-[. De plus, il apparaît assez vite que ce C-[n'est pas le seul problème avec les codes terminaux de stock: les modificateurs sont la plupart du temps effacés des informations transmises. Nous devons personnaliser le terminal pour la même raison que nous personnalisons emacs: ce serait tellement plus pratique si nous le faisions.
À ce stade, vous oserez regarder en profondeur la documentation de votre terminal: les pages de manuel loadkeys(1)
pour la console linux, pour xterm
xterm(1)
dans la section Liaisons de touches personnalisées et tout ce que je ne sais pas pour les autres terminaux. Dans KDE konsole
, vous pouvez définir des traductions personnalisées dans Paramètres / Modifier le profil actuel ...
puis Clavier . Voici un extrait ~/.local/share/konsole/Test.keytab
après avoir joué avec cette dernière boîte de dialogue:
key [+Ctrl+AnyModifier : "\EO*["
Une fois que vous avez l'envoi de terminal ESC O 5 [
pour
C-[(comme dans la configuration ci - dessus), vous pouvez revenir à emacs. Bien sûr, vous n'avez pas encore terminé.
Pour indiquer à emacs le dialecte utilisé par un terminal donné, vous pouvez ajuster input-decode-map
. Oui, c'est fortuitement celui-là même que nous avons modifié au début de cette histoire, et c'est celui-là même que
term/xterm.el
touche xterm. Un bon endroit pour le réglage est tty-setup-hook
(voir section 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))
)
)))
Sachez que ce hook ne fonctionne que si vous êtes dans un terminal. Ainsi, vous ne pouvez pas insérer ici le code pour l'initialisation du système de fenêtres. Voici la fonction de traduction en elle-même:
(defun map-my-term-codes (map)
(define-key map (kbd "M-O 5 [")
[control-bracketleft])
)
Et puis vous pouvez vous reposer: c'est la fin du voyage. Bien sûr, si vous ne vous souciez pas des terminaux, c'est rapide car vous éviterez toute la partie douloureuse. Mais vous admettez que c'est aussi assez incomplet.
Deux notes finales:
Je choisis ESC O 5 [
de coder C-[. Ce n'est qu'un exemple: je ne prétendrai pas que c'est un bon choix. Seule la 5
partie, ce qui signifie C-, semble obéir à une sorte de convention établie
configurer la console linux laisse un mauvais goût: il ne semble pas possible de faire la liaison sans utiliser un symbole existant intermédiaire , et ceux dont j'aurais besoin
n'existent pas . J'utilise des symboles dans la plage F21- F246comme dans la plupart des exemples Internet, mais ce n'est pas très satisfaisant. C'est correct pour quelques liaisons non liées, mais cela ne servira pas de schéma systématique.
Éditer
- J'ai complété cela avec le Esccas - qui a sa propre personnalité - dans un autre post: Comment supprimer les liaisons à la clé de préfixe ESC
voici un fragment d'une configuration pour se nourrir loadkeys
. Je le mets dans /root/custom.kmap et le charge quand j'en ai besoin (ce qui est rare). Ma configuration actuelle mappe également des flèches et différentes combinaisons de modificateurs, mais elle est plutôt longue, le choix des symboles et des séquences est discutable, et je ne suis pas sûr que les codes clés de mon clavier correspondent aux vôtres. Gardons-le donc à son niveau: ce n'est rien d'autre qu'une illustration.
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["