Em um sistema Debian, pressionar a END
tecla 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 kend
e em end
vez de apenas end
? (o mesmo para khome
e home
)
EDITAR
Como dito no comentário de Johan Myréen, khome
string é 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,
home
ekhome
é que akhome
sequência é a sequência que pressiona a tecla Home, enquantohome
sequê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 umaend
capacidade, apenaskend
.kend
é definido como\EOF
no terminfo , enquanto o terminal gera\E[F
? Isso é um bug no terminfo do Debian ? E como ncurses consegue detectá-lo,KEY_END
no entanto?Respostas:
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,infocmp
está mostrando que a descrição usa o modo de aplicativo. Ohome
recurso é enviado ao terminal, informando como mover o cursor para a posição inicial (superior esquerda) e não é o mesmo quekhome
(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
kend
versusend
é 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 decub1
(mova o cursor para trás uma coluna).O ncurses reconhece a tecla
KEY_END
porque o aplicativo que você está usando chamará akeypad
função para inicializar o terminal usando osmkx
(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
tput
para alternar o modo (e obter resultados diferentes deshowkey
):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:
getch
página de manual)fonte
keypad
função. Mas com a pergunta "como ncurses consegue detectá-lo comoKEY_END
" Eu quis dizer "comokeypad
decodificações^[[F
emkend
" (considerando quekeypad
os usos terminfo base de dados para interpretar os keychords). Se entendi corretamente, isso acontece porqueshowkey -a
está no modo cursor, enquanto ncurses application está no modo application.showkey
nã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 terminalshowkey
não alternar entre os modos, ele usa algum estado padrão, seja qual for o nome. O ponto é queshowkey
imprime^[[F
, não^[OF
, o que leva à minha confusão. (Eu usei apenasshowkey
para 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.)tput smkx
e obter resultados diferentes.less
utilitá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 iniciandoless
e 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.)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 AplicativoESC 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 ".
fonte