¿Por qué la tecla END no tiene entrada terminfo?

8

En un sistema Debian, presionar la ENDtecla 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 kendy en endlugar de solo end? (lo mismo para khomey home)

EDITAR

Como se dijo en el comentario de Johan Myréen, khomecadena 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,
Igor Liferenko
fuente
1
La diferencia entre homey khomees que la khomecadena es la secuencia que produce la tecla Inicio, mientras que la homecadena es la secuencia que debe enviarse al terminal para mover el cursor a la posición inicial. Que yo sepa, terminfo no define una endcapacidad, solo kend.
Johan Myréen
@ JohanMyréen ¿Podría explicar qué es la "posición inicial" de un cursor con un ejemplo? ¿Y por qué kendse define como \EOFen terminfo , mientras que el terminal genera \E[F? ¿Es esto un error en la terminfo de Debian ? ¿Y cómo ncurses logra detectarlo KEY_END?
Igor Liferenko
La posición de inicio es la esquina superior izquierda de la pantalla.
Johan Myréen

Respuestas:

10

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 te infocmpestá mostrando que la descripción usa el modo de aplicación. La homecapacidad 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 que khome(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 kendversus endes 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 de cub1(mover el cursor una columna hacia atrás).

ncurses reconoce la clave KEY_ENDporque la aplicación que está utilizando llamará a la keypadfunción para inicializar el terminal usando smkx(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 tputpara cambiar el modo (y obtener diferentes resultados de showkey):

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[H     27 0033 0x1b
         91 0133 0x5b
         72 0110 0x48
^C        3 0003 0x03
^D        4 0004 0x04
$ tput smkx
$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[OH     27 0033 0x1b
         79 0117 0x4f
         72 0110 0x48

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:

Thomas Dickey
fuente
Sí, estoy usando la keypadfunción. Pero con la pregunta "¿cómo se las arregla para ncurses detectará como KEY_END" quería decir "cómo keypaddecodifica ^[[Fen kend" (teniendo en cuenta que keypadlos usos de información de terminal de base de datos para interpretar los keychords). Si entendí correctamente, esto sucede porque showkey -aestá en modo cursor, mientras que la aplicación ncurses está en modo aplicación.
Igor Liferenko
showkeyno 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 terminal
Thomas Dickey,
Si showkeyno cambia entre modos, entonces usa algún estado predeterminado, como se llame. El punto es que las showkeyimpresiones ^[[F, no ^[OF, que conducen a mi confusión. (Solía showkeyrepresentar visualmente el teclado real que está enviando el terminal presionando un botón del teclado, sin sospechar que puede haber algunas sutilezas involucradas).
Igor Liferenko
Sí, ese es el modo "normal" (la forma habitual de referirse a esto). Por supuesto, puede inicializar su terminal usando tput smkxy obtener resultados diferentes.
Thomas Dickey
Creo que hay un error en la lessutilidad: 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 iniciando lessy presionando la tecla Intro del teclado después de escribir /; saldrá ESCOM, en lugar de hacer lo que debe hacer la tecla Intro).
Igor Liferenko
5

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ón ESC 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 ".

Johan Myréen
fuente
¿Cuál es el procedimiento para cambiar al "modo de aplicación"? ¿Lo hacen ncurses ?
Igor Liferenko