Sur un système Debian, une pression sur la END
touche génère ^[[F
:
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[F 27 0033 0x1b
91 0133 0x5b
70 0106 0x46
Mais pourquoi ce clavier n'est-il pas en terminfo ?
$ infocmp -1 | grep end
kend=\EOF,
Néanmoins, ncurses parvient à le reconnaître correctement comme KEY_END
. Comment?
TERM
est xterm-256color
BTW, quelle est la motivation derrière avoir kend
et end
au lieu de juste end
? (pareil pour khome
et home
)
ÉDITER
Comme dit dans le commentaire de Johan Myréen, la khome
chaîne est la séquence produite par la touche Home. Mais sur Debian, appuyer sur la touche Accueil produit home
. Pourquoi?
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[H 27 0033 0x1b
91 0133 0x5b
72 0110 0x48
$ infocmp -1 | grep home
home=\E[H,
khome=\EOH,
home
etkhome
est que lakhome
chaîne est la séquence qui produit la touche Home, tandis que lahome
chaîne est la séquence qui doit être envoyée au terminal pour déplacer le curseur à la position d'origine. À ma connaissance, terminfo ne définit pas uneend
capacité, justekend
.kend
est défini comme\EOF
dans terminfo , alors que le terminal génère\E[F
? Est-ce un bogue dans le terminfo de Debian ? Et comment ncurses parvient-il à le détecterKEY_END
quand même?Réponses:
La réponse de Johan Myréen était proche, mais pas exactement le problème: la plupart des émulateurs de terminaux que vous utiliserez ont des modes normal et d' application pour les touches spéciales. Les descriptions des terminaux sont écrites pour un mode, ce qui correspond à ce qu'une application plein écran utilise. D'autres applications (comme un shell interactif ) n'initialisent généralement pas l'écran pour utiliser le mode d' application . Bash en est un exemple.
En mode normal , les terminaux xterm et similaires envoient escape
[
(CSI) tandis qu'en mode application , leurs claviers envoient escapeO
(SS3). Dans la syntaxe terminfo, cet échappement est\E
. Donc ,infocmp
vous montre que la description utilise le mode d'application. Lahome
capacité est envoyée au terminal, lui indiquant comment déplacer le curseur vers la position d' origine (en haut à gauche), et n'est pas la même quekhome
(envoyée depuis le terminal à l'aide du clavier).Les applications plein écran (telles que celles utilisant ncurses) peuvent envoyer les chaînes de capacité de terminal pour initialiser le clavier. Certaines descriptions de terminaux mettent le terminal en mode application, d'autres non.
L'utilisation de
kend
versusend
est une convention de dénomination: dans terminfo par convention, tout nom commençant par k fait référence à une touche spéciale (touche de fonction, touche de curseur, touche de clavier) pour indiquer clairement qu'il s'agit de chaînes à lire par une application. Par exemple,kcub1
( touche curseur vers l'arrière ) est différent decub1
(déplacer le curseur d'une colonne vers l'arrière).ncurses reconnaît la clé
KEY_END
car l'application que vous utilisez appellera lakeypad
fonction pour initialiser le terminal en utilisant lesmkx
(le mnémonique signifie "démarrer le mode de transmission clavier"). Cela peut / peut ne pas réellement activer le mode d'application. La description du terminal de la console Linux ne le fait pas, celle de xterm le fait.En principe, vous pouvez utiliser
tput
pour changer de mode (et obtenir des résultats différentsshowkey
):Comme complication, les curses ne reconnaîtront qu'un seul nom pour une chaîne. Certains terminaux (tels que xterm) émulent des terminaux matériels plus anciens en utilisant des noms différents pour les touches du clavier d'édition. Dans la FAQ xterm listée ci-dessous, il est possible de nommer la touche "Accueil" "Insérer" ...
Lectures complémentaires:
getch
page de manuel)la source
keypad
fonction. Mais la question « comment ncurses parvient à détecter commeKEY_END
» je voulais dire « commentkeypad
décodages^[[F
danskend
» (considérant que leskeypad
utilisations terminfo base de données pour interpréter les keychords). Si j'ai bien compris, cela se produit carshowkey -a
est en mode curseur, tandis que l'application ncurses est en mode application.showkey
ne bascule pas entre les modes normal / d'application. C'est un programme spécifique à Linux, faisant des hypothèses sur la console Linux, plutôt que d'utiliser la base de données du terminalshowkey
ne passe pas d'un mode à l'autre, il utilise un état par défaut, quel qu'il soit. Le fait est que lesshowkey
impressions^[[F
, non^[OF
, ce qui conduit à ma confusion. (Je viensshowkey
de représenter visuellement le véritable clavier qui est envoyé par le terminal en appuyant sur un bouton du clavier, sans soupçonner qu'il puisse y avoir des subtilités.)tput smkx
et obtenir des résultats différents.less
utilitaire: il se met en mode application, mais ne parvient pas à interpréter la touche d'entrée du clavier. Dois-je soumettre un rapport de bug? (Vous pouvez vérifier cela en démarrantless
et en appuyant sur la touche Entrée du clavier après avoir tapé/
- cela produiraESCOM
, au lieu de faire ce que la touche Entrée doit faire.)Le problème avec la touche Accueil est que les terminaux physiques et plus tard les émulateurs de terminaux qui les émulent ont deux modes: le mode normal et le mode d'application, et les séquences d'échappement sont différentes selon le mode dans lequel se trouve le terminal. Terminfo ne gère pas bien cela. En mode normal (aka "Mode curseur"), la séquence d'échappement de la touche Fin est
ESC [ F
, en mode ApplicationESC O F
. Googler pour ce problème révèle tout le gâchis.Modifier à partir de la source terminfo:
les touches de curseur sont alors supposées être en "mode curseur" et les définitions des touches de curseur doivent correspondre à cette hypothèse, sinon l'application peut échouer. Il est également prévu que les applications transmettent toujours la chaîne au terminal avant de quitter. "
la source