Quantos bytes uma tecla pode retornar? E deve uma chave metafied retornar mais?

2

Eu tenho trabalhado com esse leitor de entrada ultimamente. Atualmente, ele imprime apenas um relatório para stdout para cada tecla pressionada enquanto é executado, mas eu gostaria de graduá-lo para um propósito mais alto, mais cedo ou mais tarde, já que parece estar chegando ok. Até agora, tem algumas coisas:

  1. Toda a sua saída é o resultado de alguns processos simultâneos em um único pipeline.
  2. Ele interpreta e relata cada pressionamento de tecla assim que é feito.
  3. (até onde eu sei) informa quantos bytes por tecla pressionada são enviados para cada tecla pressionada.

Por exemplo, se eu o executar e pressionar as seguintes combinações de teclas / teclas em ordem ...

  1. a
  2. CTRL + J
  3. ALT + ESPAÇO
  4. UP
  5. ALT + UP

... imprime o seguinte na tela do terminal, uma linha por pressionamento de tecla e assim que cada pressionamento de tecla é feito:

 a:97
 \n:10
 0:160
 \e:27 [:91 A:65
 \e:27 [:91 1:49 ;:59 5:53 A:65

... onde cada byte em cada tecla é impresso como ...

<space>(printable char|\C-escape|\octal-escape):[decimal byte value]

... como eu considerei apropriado.

Algumas delas me confundem:

  1. Embora eu ache que tentei todas as chaves, e embora tenha definido definitivamente stty para enviar caracteres de 8 bits (w / cs8 ) , o A combinação ALT + SPACE parece ser a única que reporta qualquer byte constituinte maior que o decimal ASCII 127.
    • Isso é especialmente confuso, pois suponho que tenha algo a ver com o modificador ALT meta fying (um conceito que eu compreendo muito pouco) a sequência de teclas, mas aparentemente em todos os outros casos ALT + anykey prefixam um ESC para o seqüência, ou de outra forma sutilmente modifica uma seqüência já escapada.
    • O ALT não está mudando a sequência enviada para o maior intervalo entre 128 e 255?
    • (em um comentário abaixo, derobert indica que o leitor foi interpretado e relatado com sucesso na sequência UTF-8 compose de bytes múltiplos) Observação: locale informa que todas as categorias LC_* estão definidas como en_US.UTF-8
  2. Também é preocupante que enquanto eu pareço obter todos os bytes para cada pressionamento de tecla, em sua forma atual meu script irá delimitar pressionamentos de tecla em 8 agora 32 bytes no máximo.
    • Eu pensava que 8 bytes era suficiente, mas agora eu duvido quando considero se caracteres multibyte em outras localidades podem ser combinados com algumas das sequências de escape mais longas que estou vendo. E assim eu estendi o buffer - mas com menos certeza do que 8 bytes inicialmente me forneceram.
    • Existe um limite superior para quantos bytes podem ser enviados em uma única tecla?
por mikeserv 31.03.2015 / 17:21

1 resposta

2

Isso é realmente várias perguntas. Alguns lidam com o comportamento específico do terminal e alguns lidam com a composição.

Primeiro, há uma questão sobre o comportamento esperado de Alt usado como um modificador. Algumas pessoas igualam a tecla Alt (que é rotulada em muitos teclados) com Meta (que raramente é rotulado como tal nos teclados de terminal). E alguns vão além, igualando-o ao personagem de escape. Chame isso de um uso convencional . No xterm, pelo menos, a associação é configurável (desde o patch # 122 em 1999 , o recurso metaSendsEscape e o patch # 225 em 2007 adicionaram altIsNotMeta e altSendsEscape Recursos). Outros emuladores de terminal (e seus usuários, talvez) não são tão flexíveis. Portanto, há uma convenção que equivale a escape e meta. Convenções não são padrões.

O comportamento documentado da meta-chave está na página de manual do terminfo (5) :

If the terminal has a "meta key" which acts as a shift key, setting the 8th bit of any character transmitted, this fact can be indicated with km. Otherwise, software will assume that the 8th bit is parity and it will usually be cleared. If strings exist to turn this "meta mode" on and off, they can be given as smm and rmm.

Não há um comportamento padrão para o caso em que o modo meta está desativado (apenas convenção).

Dependendo do recurso eightBitInput no xterm, ele pode construir códigos maiores que 128 usando a meta-chave. Por exemplo, no patch # 183 em 2003 , essa alteração foi feita para evitar que o modo meta produzir ilegal UTF-8:

  • modify handling of eightBitInput resource in UTF-8 mode to translate the value into UTF-8. Otherwise an illegal UTF-8 code is sent to the application (report by Bram Moolenaar).
No geral, no entanto, a maioria das seqüências de escape que você pode usar com terminais e as seqüências de escape convencionais que seus teclados retornam usam ASCII de 7 bits. VT100s não são exceção a isso; esse foi o ponto dessa mudança do patch # 177 em 2002 :

  • modify parser tables to improve detection of malformed control sequences, making xterm behave more like a real DEC terminal (patch by Paul Williams).

Ou seja, as tabelas de analisadores são principalmente organizadas para ignorar o oitavo bit dos caracteres de entrada. Outros terminais podem ignorar esse aspecto, mas ainda copiar as seqüências de escape usadas para o teclado do xterm. O resultado é que você principalmente vê o ASCII de 7 bits.

Estou usando o xterm como exemplo, já que a maior parte do comportamento que você provavelmente verá começou com o xterm (e a maior parte do restante veio do rxvt). Com o xterm, você pode ter vários casos em que você obtém seqüências de escape razoavelmente longas de uma chave, por exemplo,

  • usando o modo modifyOtherKeys , que atribui uma seqüência de escape para (a maioria) das teclas no teclado,
  • usando o recurso translations , que permite enviar "qualquer" sequência de caracteres e
  • usando o recurso DECUDK , que envia uma string definida pelo aplicativo (como uma seqüência de dígitos hexadecimais).

Outros terminais (como o OSX Terminal.app e iTerm2) também podem enviar strings configuráveis pelo usuário. Deste ponto de vista, não há limite bem definido no número de bytes enviados por uma chave.

Por outro lado, compor é mais bem definido: seu resultado é um caractere (ou poderia ser vários caracteres?) em uma dada codificação. Assuma apenas um único caractere. O comprimento máximo padrão de um caractere codificado em UTF-8 é de 4 bytes. Enquanto você poderia ver uma chave configurada pelo usuário enviando esses dados, principalmente (por causa de compatibilidade e convenções) você não verá os dois (seqüências de escape e caracteres codificados) misturados.

Leitura adicional:

por 17.08.2016 / 03:41