Como emuladores de terminal lidam com Shift + FKeys?

3

Esta questão é inspirada por outra pergunta no vi.SE . Lá, o OP tem problemas com a combinação de teclas Shift + F8 ao executar vim dentro de urxvt . Essa combinação de teclas nunca funcionará em vim porque o emulador de terminal não passa corretamente (pelo menos do que eu consegui depurar).

Eu não entendi como as chaves F são manipuladas pelos emuladores de terminal.

Em urxvt

  • Quando eu pressiono Shift + F8 ~ é ecoado.
  • Quando eu pressiono F7 (ou qualquer outra tecla F) ~ é ecoado também.

Em vim dentro de urxvt

  • Quando pressiono Shift + F8 , obtenho o efeito de ~~ .
  • Quando pressiono Shift + F7 , obtenho o efeito de ~ .
  • Quando pressiono Shift + F6 , obtenho o efeito de ~~~ .

Em xterm , por outro lado:

  • Quando eu pressiono Shift + F8 ;2~ é ecoado.
  • Quando pressiono F8 (ou qualquer outra tecla F), apenas ~ é ecoado.

Não entendo por que recebo essa saída.

Para depurar ainda mais, executei xev e obtive o seguinte:

Para F8

KeyPress event, serial 29, synthetic NO, window 0x2000001,
    root 0x7e, subw 0x0, time 17730758, (431,256), root:(432,275),
    state 0x0, keycode 74 (keysym 0xffc5, F8), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

Para a esquerda Shift

KeyPress event, serial 32, synthetic NO, window 0x2000001,
    root 0x7e, subw 0x0, time 17733031, (431,256), root:(432,275),
    state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

E para a direita Shift

KeyPress event, serial 32, synthetic NO, window 0x2000001,
    root 0x7e, subw 0x0, time 17733372, (431,256), root:(432,275),
    state 0x0, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

No entanto, não vejo absolutamente nada estranho lá.

Como essas teclas (as teclas F) são tratadas pelos emuladores de terminal? O que os emuladores de terminal recebem de x11 ? E como eles passam mais para o programa que está sendo executado dentro deles?

Eu sempre acreditei que as teclas F eram apenas uma combinação de Esc mais um dígito. Agora eu achei que estava errado.

Adendo

As teclas F sem Shift funcionam bem em vim dentro de urxvt . Se eu fizer:

:map <f8> :echo "yay"<CR>

Eu faço corretamente o "yay" ecoado quando pressiono F8 .

    
por grochmal 27.06.2016 / 23:42

2 respostas

2

A interface entre o terminal e o aplicativo envia bytes, não chaves. Os caracteres imprimíveis são interpretados como a sequência de bytes correspondente à codificação de caracteres do terminal. Teclas de função são codificadas como seqüências de escape. Existem convenções comuns para essas sequências de escape, mas elas não são completamente padronizadas.

Para informações mais gerais, consulte Como fazer entrada de teclado e trabalho de saída de texto? . Para obter mais informações, consulte também Existe alguma razão pela qual eu recebo ^ [[A quando eu pressiono a seta para cima na tela de login do console? e tabela de vinculações de teclas?

Todas as seqüências de escape da tecla de função começam com o caractere de escape e a maioria delas termina com ~ . O Vim reconhece um número de seqüências de escape com base em suas configurações de tempo de compilação e as informações que ele tem no terminal. Se o Vim não reconhecer uma sequência de escape, ele a ignora, mas o Vim não sabe quanto tempo a sequência de escape é (não assume que o último caractere seja um ~ , nem sempre é o caso) . Muitas vezes, há um ~ perdido após a parte que o Vim reconhece, às vezes mais.

Você pode ver exatamente o que o terminal envia pressionando Ctrl + V primeiro, em um shell ou no modo de inserção do Vim.

Você pode informar ao Vim sobre a tecla de função correspondente a uma seqüência de escape com :set , por exemplo

:set <S-F8>=^[[19;2~

(substitua a peça após ^[ pelo que o seu terminal realmente envia).

    
por 28.06.2016 / 02:48
3

Algumas teclas são usadas como modificadores ( shift , controle são os mais usados). Os emuladores de terminal recebem uma série de eventos X , que você pode ver com xev . O emulador de terminal combina alguns desses eventos como shift a usando bibliotecas X para obter A . Para outros casos, como teclas de função e teclas de cursor (chamadas "chaves especiais" ), não há transformação predefinida pelas bibliotecas X. O emulador de terminal decide se e quando usar esses modificadores para criar seqüências de escape diferentes enviadas por chaves especiais.

Diferentes emuladores de terminal podem usar regras diferentes para isso: não há padrão para as sequências que podem ser enviadas. Existem apenas convenções , por exemplo, decidindo imitar certos terminais, ou estender coisas fazendo novas sequências que nenhum outro terminal faz.

Tanto o rxvt quanto o xterm usam esses modificadores para fornecer sequências de teclas de função diferentes, permitindo que programas executados nos terminais atuem como se o seu terminal tivesse algumas dúzias de teclas de função.

No entanto - os terminais também podem ter um modo , definido por sequências de controle da aplicação para o terminal que altera as seqüências de escape enviadas para teclas de função. É comum usar essas seqüências de controle de comutação de modo em programas de tela inteira (como o vim). Então você vê diferenças.

Como não há padrão , há uma descrição do terminal para cada terminal, que descreve seu comportamento (usando a variável de ambiente TERM ). Para a maioria dos terminais, a descrição inicializa o terminal para usar o modo de aplicação (tanto para o teclado quanto para as teclas do cursor). Aplicativos de tela inteira usam essas seqüências de inicialização e usam as teclas de função e cursor listadas nessas descrições, para que elas obtenham um comportamento consistente.

Nem todos os terminais enviaram seqüências de escape para teclas de função. Por exemplo, a estação de trabalho altos usou um caractere de circunflexo, wyse-85 suportou um modo de 8 bits usando 3 em vez de 3[ (CSI), qnx usado 7 . Mas a maioria começou com o caractere de escape ASCII. Personagens finais são uma história diferente. Cerca de metade das chaves de função modificadas do rxvt terminam com um caractere diferente de ASCII tilde ~ (há uma tabela no FAQ ncurses ilustrando isso). Devido a essas diferenças, é importante que a descrição do terminal corresponda ao terminal real.

Na versão atual do vim (7.3), não vejo problema. Ele reconhece deslocado F8 . Alguns anos atrás, houve um problema. A checagem do vim para teclas de função não esperava um ponto-e-vírgula, como é enviado pelo xterm. Assim que o ponto-e-vírgula foi contado, ele parou de reconhecer a tecla de função. Você pode ter uma versão antiga do vim ou alguns mapeamentos de teclas que interferem no reconhecimento das chaves. O vim pode agora (em qualquer versão que você esteja usando), mas não olha a descrição do terminal para as teclas estendidas, mas depende de suas próprias tabelas. Para complicar a situação, o vim pode usar um recurso xterm (chamado tcap-query ) para obter as seqüências de chaves reais enviadas pelo xterm.

Por outro lado, o vim provavelmente possui um mapeamento que fornece resultados diferentes para as seqüências de chaves rxvt. Não existe uma distinção especial entre o seu F6 ( \E[29~ ), deslocado F7 ( \E[31~ ) e deslocado F8 ( \E[32~ ).

Leitura adicional:

por 27.06.2016 / 23:55