Por que a chave END não possui entrada terminfo?

8

Em um sistema Debian, pressionar a ENDtecla gera ^[[F:

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^[[F     27 0033 0x1b
         91 0133 0x5b
         70 0106 0x46

Mas por que esse keychord não está no terminfo ?

$ infocmp -1 | grep end
kend=\EOF,

No entanto, ncurses consegue reconhecê-lo corretamente como KEY_END. Quão?

TERM é xterm-256color

BTW, qual é a motivação por trás de ter kende em endvez de apenas end? (o mesmo para khomee home)

EDITAR

Como dito no comentário de Johan Myréen, khomestring é a sequência que pressiona a tecla Home. Mas no Debian, pressionar a tecla Home produz 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
fonte
1
A diferença entre homee khomeé que a khomesequência é a sequência que pressiona a tecla Home, enquanto homesequência é a sequência que deve ser enviada ao terminal para mover o cursor para a posição inicial. Que eu saiba, terminfo não define uma endcapacidade, apenas kend.
Johan Myréen 01/08/19
@ JohanMyréen Você poderia explicar o que é a "posição inicial" de um cursor com um exemplo? E por que kendé definido como \EOFno terminfo , enquanto o terminal gera \E[F? Isso é um bug no terminfo do Debian ? E como ncurses consegue detectá-lo, KEY_ENDno entanto?
Igor Liferenko
A posição inicial é o canto superior esquerdo da tela.
Johan Myréen 01/08/19

Respostas:

10

A resposta de Johan Myréen foi próxima, mas não exatamente o problema: a maioria dos emuladores de terminal que você usará possui modos normal e de aplicativo para teclas especiais. As descrições dos terminais são escritas para um modo, que corresponde ao que um aplicativo de tela cheia usa. Outros aplicativos (como um shell interativo ) normalmente não inicializam a tela para usar o modo de aplicativo . Bash é um exemplo disso.

No modo normal , xterm e terminais semelhantes enviam escape[(CSI) enquanto no modo de aplicativo , seus teclados enviam escapeO(SS3). Na sintaxe terminfo, esse escape é \E. Então, infocmpestá mostrando que a descrição usa o modo de aplicativo. O homerecurso é enviado ao terminal, informando como mover o cursor para a posição inicial (superior esquerda) e não é o mesmo que khome(enviado do terminal usando o teclado).

Aplicativos de tela cheia (como aqueles que usam ncurses) podem enviar as strings de capacidade do terminal para inicializar o teclado. Algumas descrições de terminal colocam o terminal no modo de aplicativo, outras não.

O uso de kendversus endé uma convenção de nomenclatura: em terminfo por convenção, qualquer nome que comece com k se refere a uma tecla especial (tecla de função, tecla do cursor, tecla do teclado) para deixar claro que essas são cadeias de caracteres para serem lidas por um aplicativo. Por exemplo, kcub1( tecla do cursor para trás ) é diferente de cub1(mova o cursor para trás uma coluna).

O ncurses reconhece a tecla KEY_ENDporque o aplicativo que você está usando chamará a keypadfunção para inicializar o terminal usando o smkx(o mnemônico significa "iniciar o modo de transmissão do teclado"). Isso pode ou não pode realmente ativar o modo de aplicativo. A descrição do terminal do console Linux não, a do xterm.

Em princípio, você pode usar tputpara alternar o modo (e obter resultados diferentes 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 complicação, as maldições reconhecerão apenas um nome para uma string. Alguns terminais (como o xterm) emulam terminais de hardware mais antigos usando nomes diferentes para as teclas no teclado de edição. Nas perguntas frequentes do xterm listadas abaixo, há a possibilidade de nomear a tecla "Página inicial" "Inserir" ...

Leitura adicional:

Thomas Dickey
fonte
Sim, estou usando a keypadfunção. Mas com a pergunta "como ncurses consegue detectá-lo como KEY_END" Eu quis dizer "como keypaddecodificações ^[[Fem kend" (considerando que keypados usos terminfo base de dados para interpretar os keychords). Se entendi corretamente, isso acontece porque showkey -aestá no modo cursor, enquanto ncurses application está no modo application.
Igor Liferenko
showkeynão alterna entre os modos normal / de aplicativo. É um programa específico-Linux, fazer suposições sobre o console Linux, em vez de usar o banco de dados do terminal
Thomas Dickey
Se showkeynão alternar entre os modos, ele usa algum estado padrão, seja qual for o nome. O ponto é que showkeyimprime ^[[F, não ^[OF, o que leva à minha confusão. (Eu usei apenas showkeypara representar visualmente a keychord real que está sendo enviado pelo terminal pressionando um botão do teclado, sem suspeitar que pode haver alguns sutilezas envolvidas.)
Igor Liferenko
Sim, esse é o modo "normal" (a maneira usual de se referir a isso). Obviamente, você pode inicializar seu terminal usando tput smkxe obter resultados diferentes.
Thomas Dickey
Eu acho que existe um bug no lessutilitário: ele se coloca no modo de aplicativo, mas falha na interpretação da tecla enter do teclado. Devo enviar um relatório de bug? (Você pode verificar isso iniciando lesse que pressiona o teclado tecla enter depois de digitar /- a saída será ESCOM, em vez de fazer o que a tecla Enter deve fazer.)
Igor Liferenko
5

O problema com a tecla Home é que os terminais físicos e, posteriormente, os emuladores de terminal que os emulam têm dois modos: normal e Modo de Aplicação, e as seqüências de escape são diferentes dependendo do modo em que o terminal está. Terminfo não lida bem com isso. No modo normal (também conhecido como "Modo do Cursor"), a sequência de escape da tecla Fim é ESC [ F, no modo Aplicativo ESC O F. Pesquisar no Google por esse problema revela toda a bagunça.

Editar a partir da fonte terminfo:

presume-se que as teclas do cursor estejam no "Modo Cursor" e as definições das teclas do cursor devem corresponder a essa suposição; caso contrário, o aplicativo poderá falhar. Também é esperado que os aplicativos sempre transmitam a string para o terminal antes de sair ".

Johan Myréen
fonte
Qual é o procedimento para alternar para o "modo de aplicativo"? É feito por ncurses ?
Igor Liferenko