En un sistema Debian, presionar la END
tecla genera ^[[F
:
$ showkey -a
Press any keys - Ctrl-D will terminate this program
^[[F 27 0033 0x1b
91 0133 0x5b
70 0106 0x46
Pero, ¿por qué este teclado no está en terminfo ?
$ infocmp -1 | grep end
kend=\EOF,
Sin embargo, ncurses logra reconocerlo correctamente como KEY_END
. ¿Cómo?
TERM
es xterm-256color
Por cierto, ¿cuál es la motivación detrás de tener kend
y en end
lugar de solo end
? (lo mismo para khome
y home
)
EDITAR
Como se dijo en el comentario de Johan Myréen, khome
cadena es la secuencia que produce la tecla Inicio. Pero en Debian se produce presionar la tecla Inicio home
. ¿Por qué?
$ 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
ykhome
es que lakhome
cadena es la secuencia que produce la tecla Inicio, mientras que lahome
cadena es la secuencia que debe enviarse al terminal para mover el cursor a la posición inicial. Que yo sepa, terminfo no define unaend
capacidad, solokend
.kend
se define como\EOF
en terminfo , mientras que el terminal genera\E[F
? ¿Es esto un error en la terminfo de Debian ? ¿Y cómo ncurses logra detectarloKEY_END
?Respuestas:
La respuesta de Johan Myréen fue cercana, pero no exactamente el problema: la mayoría de los emuladores de terminal que usará tienen modos normales y de aplicación para teclas especiales. Las descripciones de terminal se escriben para un modo, que corresponde a lo que usa una aplicación de pantalla completa. Otras aplicaciones (como un shell interactivo ) generalmente no inicializan la pantalla para usar el modo de aplicación . Bash es un ejemplo de eso.
En modo normal , xterm y terminales similares envían escape
[
(CSI) mientras que en modo de aplicación , envían sus teclados escapeO
(SS3). En la sintaxis terminfo, ese escape es\E
. Entonces teinfocmp
está mostrando que la descripción usa el modo de aplicación. Lahome
capacidad se envía al terminal, diciéndole cómo mover el cursor a la posición de inicio (arriba a la izquierda), y no es lo mismo quekhome
(enviado desde el terminal usando el teclado).Las aplicaciones de pantalla completa (como las que usan ncurses) pueden enviar cadenas de capacidad de terminal para inicializar el teclado. Algunas descripciones de terminal ponen el terminal en modo de aplicación, otras no.
El uso de
kend
versusend
es una convención de nomenclatura: en terminfo por convención, cualquier nombre que comience con k se refiere a una tecla especial (tecla de función, tecla de cursor, tecla del teclado) para dejar en claro que estas son cadenas que debe leer una aplicación. Por ejemplo,kcub1
( tecla de cursor hacia atrás ) es diferente decub1
(mover el cursor una columna hacia atrás).ncurses reconoce la clave
KEY_END
porque la aplicación que está utilizando llamará a lakeypad
función para inicializar el terminal usandosmkx
(el mnemotécnico significa "iniciar el modo de transmisión de teclado"). Eso puede o no activar el modo de aplicación. La descripción del terminal de la consola Linux no lo hace, la de xterm sí.En principio, podría usar
tput
para cambiar el modo (y obtener diferentes resultados deshowkey
):Como complicación, las maldiciones reconocerán solo un nombre para una cadena. Algunos terminales (como xterm) emulan terminales de hardware más antiguos utilizando diferentes nombres para las teclas en el teclado de edición. En las preguntas frecuentes de xterm enumeradas a continuación, existe la posibilidad de nombrar esa tecla "Inicio" "Insertar" ...
Otras lecturas:
getch
página de manual)fuente
keypad
función. Pero con la pregunta "¿cómo se las arregla para ncurses detectará comoKEY_END
" quería decir "cómokeypad
decodifica^[[F
enkend
" (teniendo en cuenta quekeypad
los usos de información de terminal de base de datos para interpretar los keychords). Si entendí correctamente, esto sucede porqueshowkey -a
está en modo cursor, mientras que la aplicación ncurses está en modo aplicación.showkey
no cambia entre los modos normal / de aplicación. Es un programa específico de Linux, que hace suposiciones sobre la consola de Linux, en lugar de usar la base de datos del terminalshowkey
no cambia entre modos, entonces usa algún estado predeterminado, como se llame. El punto es que lasshowkey
impresiones^[[F
, no^[OF
, que conducen a mi confusión. (Solíashowkey
representar visualmente el teclado real que está enviando el terminal presionando un botón del teclado, sin sospechar que puede haber algunas sutilezas involucradas).tput smkx
y obtener resultados diferentes.less
utilidad: se pone en modo de aplicación, pero luego no puede interpretar la tecla enter del teclado. ¿Debo enviar un informe de error? (Puede verificar esto iniciandoless
y presionando la tecla Intro del teclado después de escribir/
; saldráESCOM
, en lugar de hacer lo que debe hacer la tecla Intro).El problema con la tecla de inicio es que los terminales físicos y más tarde los emuladores de terminal que los emulan tienen dos modos: normal y modo de aplicación, y las secuencias de escape son diferentes dependiendo del modo en que se encuentre el terminal. Terminfo no se las arregla bien con esto. En modo normal (también conocido como "Modo de cursor") la secuencia de escape de la tecla Finalizar es
ESC [ F
, en modo AplicaciónESC O F
. Buscar en Google este problema revela todo el desastre.Editar desde la fuente terminfo:
entonces se supone que las teclas del cursor están en "Modo cursor", y las definiciones de las teclas del cursor deben coincidir con esa suposición, de lo contrario la aplicación puede fallar. También se espera que las aplicaciones siempre transmitan la cadena al terminal antes de que salgan ".
fuente