Pourquoi Emacs ne fonctionnant pas dans un terminal ne peut-il pas distinguer Ctrl +; de ";"?


8

Cette question découle de ma question précédente sur emacs beta . En bref, je veux me lier C-;à une fonction Emacs dans un terminal, mais il semble que quelque chose capture cette touche avant qu'elle n'atteigne Emacs: Emacs pense que j'ai appuyé ;.

Le suspect évident est l'émulateur de terminal, mais j'en ai vérifié beaucoup (xterm, gnome-terminal, terminator, terminologie) et aucun ne fonctionne. Je peux très probablement exclure le gestionnaire de fenêtres, car dans la version GUI d'Emacs, la clé C-;fonctionne très bien. J'ai aussi essayé deux shells différents: bash et zsh, mais encore une fois sans succès.

Que puis-je essayer d'autre?


Selon votre question sur Emacs , appuyez sur Ctrl +; envoie ;à Emacs, donc rien ne le capture , ce qui se passe c'est que Ctrl +; et nu; envoyer les mêmes informations. Laquelle est-ce: capture (c'est-à-dire qu'Emacs ne reçoit rien) ou perte d'informations (c'est-à-dire qu'Emacs reçoit ;)?
Gilles 'SO- arrête d'être méchant'

il n'y a pas de code standard pour C-;dans le terminal. Que se passe-t-il si vous tapez C-v C-;en simple bash?
artm

@Gilles Je vois ;dans emacs -nwindépendamment si je frappe ;ou C-;.
WeSenseASoulInSearchOfAnswers

@artm bashcomme emacs imprime juste à nu ;.
WeSenseASoulInSearchOfAnswers

Réponses:


11

Peut-être que votre confusion vient du fait de ne pas avoir utilisé un terminal réel. À l'époque où les ordinateurs sérieux étaient de la taille de plusieurs réfrigérateurs verticaux, un terminal communiquait avec un ordinateur central via un câble série en utilisant uniquement des caractères et des caractères. Les caractères faisaient partie d'un jeu de caractères standardisé, par exemple ASCII ou EBCDIC, mais généralement ASCII. ASCII a 33 caractères de contrôle et l'opérateur du terminal les a envoyés en appuyant sur une touche spéciale (comme DEL) ou en maintenant enfoncée la touche CTRL et en appuyant sur une autre touche. L'ordinateur central n'a vu que le caractère de contrôle résultant; il ne savait pas sur quelles touches on avait appuyé pour produire le personnage.

Un programme d'émulation de terminal tel que xterm imite ce comportement. L'émulateur de terminal permet d'envoyer les 33 caractères de contrôle ASCII et Emacs recevra ces caractères s'ils sont envoyés. Mais Emacs est comme l'ordinateur central dans la description ci-dessus --- il n'a aucun moyen de savoir quelles touches ont été réellement pressées lorsque vous l'exécutez sous un émulateur de terminal. Donc, si vous appuyez sur CTRL et point-virgule, à moins que le programme d'émulation de terminal n'ait mappé ces touches sur un caractère ASCII, Emacs ne saura pas que quelque chose a été tapé.

Les émulateurs de terminal utilisent généralement les mappages suivants pour générer des caractères de contrôle :

appuyez sur la touche ASCII
--------------------
ESCAPE 27
SUPPRIMER 127
RETOUR ARRIÈRE 8
CTRL + ESPACE 0
CTRL + @ 0
CTRL + A 1
CTRL + B 2
CTRL + C 3
etc...
CTRL + X 24
CTRL + Y 25
CTRL + Z 26
CTRL + [27
CTRL + \ 28
CTRL +] 29
CTRL + ^ 30
CTRL + _ 31

Notez que CTRL +; n'apparaît pas dans cette liste. Les terminaux seront simplement envoyer généralement le caractère imprimable attribué à la touche si CTRL + touche n'est pas mis en correspondance avec un caractère de contrôle. Donc, ce que votre émulateur de terminal vous dit en envoyant; seul, il ne sait pas quoi faire lorsque vous appuyez sur CTRL + ;.

Tout cela ne s'applique que si vous utilisez un terminal ou un programme d'émulation de terminal. Si vous exécutez Emacs en tant qu'application native sous un système de fenêtres, Emacs a un accès complet aux événements de frappe et pas seulement aux caractères. Emacs peut donc voir que vous avez appuyé simultanément sur CTRL et point-virgule et vous permet d'assigner une action à cette paire de touches.

† Les terminaux ont souvent des touches de fonction et des touches fléchées qui génèrent également des séquences de caractères comprenant des caractères de contrôle. Ces séquences commencent généralement par le code ASCII 27 (ESCAPE).


3

Les terminaux transmettent des caractères (plus précisément: octets), pas des clés. Lorsque vous appuyez sur une touche ou un accord de touches comme Ctrl+ ;, ces informations doivent être codées en une séquence d'octets. Keychords représentant un caractère, comme Aou Shift+ Aou À, sont envoyés en tant que caractère: a, A, à(le dernier étant un ou deux octets selon le codage de caractères du terminal).

Les accords de touches impliquant des touches de fonction n'ont pas de caractère correspondant, ils sont donc envoyés sous forme de séquences d'échappement: une séquence d'octets commençant par le caractère d'échappement ( \edans une chaîne Emacs, apparaissant comme cyan ^[si elle est entrée littéralement dans un tampon). Quelques touches de fonction ont des octets correspondants qui sont des caractères de contrôle .

Le keychord Ctrl+ ;n'a pas de séquence d'échappement standard, donc la plupart des émulateurs de terminal génèrent le caractère ;. Cela perd l'information sur laquelle le Ctrlmodificateur a été enfoncé.

Afin de définir une liaison pour Ctrl+ ;, vous devrez configurer votre émulateur de terminal pour envoyer une séquence d'échappement différente. Je ne pense pas que vous puissiez le faire avec le terminal Gnome (Gnome est rarement configurable). Vous pouvez le faire avec Xterm. Voir Existe-t-il des terminaux Linux qui peuvent gérer toutes les combinaisons de touches? pour des instructions.

Le shell que vous pouvez exécuter dans le terminal n'est pas impliqué. Un GUI Emacs n'a aucun problème car le GUI (X11) transmet les événements d'entrée sous une forme qui code les clés et les modificateurs, pas comme une simple séquence de caractères.

Voir Comment fonctionnent la saisie au clavier et la sortie du texte? pour des informations plus détaillées sur la manière dont les entrées sont transmises de votre clavier à votre application.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.