Por que o Emacs rodando em um terminal não consegue distinguir Ctrl+; de ";"?

Por que o Emacs rodando em um terminal não consegue distinguir Ctrl+; de ";"?

Esta questão surgiu da minhapergunta anterior sobre emacs beta. Resumindo, quero vincular C-;a funções do Emacs em um terminal, mas parece que algo captura essa chave antes de chegar ao Emacs: o Emacs acha que eu pressionei ;.

O suspeito óbvio é o emulador de terminal, mas verifiquei muitos deles (xterm, gnome-terminal, terminator, terminologia) e nenhum deles funciona. Muito provavelmente posso excluir o gerenciador de janelas, porque na versão GUI do Emacs, a chave C-;funciona perfeitamente. Tentei também dois shells diferentes: bash e zsh, mas novamente sem sucesso.

O que mais posso tentar?

Responder1

Talvez a sua confusão surja por não ter usado um terminal real. Na época em que os computadores sérios eram do tamanho de várias geladeiras verticais, umterminalcomunica-se com um computador central por meio de um cabo serial usando apenas caracteres e caracteres. Os caracteres faziam parte de algum conjunto de caracteres padronizado, por exemplo, ASCII ou EBCDIC, mas normalmente ASCII. ASCII possui 33 caracteres de controle e o operador do terminal os envia pressionando uma tecla especial (como DEL) ou mantendo pressionada a tecla CTRL e pressionando outra tecla. O computador central viu apenas o caractere de controle resultante; não sabia quais teclas foram pressionadas para produzir o caractere.

Um programa de emulação de terminal como o xterm imita esse comportamento. O emulador de terminal fornece uma maneira de enviar todos os 33 caracteres de controle ASCII e o Emacs receberá esses caracteres se eles forem enviados. Mas o Emacs é como o computador central na descrição acima --- ele não tem como saber quais teclas foram realmente pressionadas quando você o executa em um emulador de terminal. Portanto, se você pressionar CTRL e ponto e vírgula, a menos que o programa de emulação de terminal tenha mapeado essas teclas pressionadas para algum caractere ASCII, o Emacs não saberá que algo foi digitado.

Emuladores de terminal normalmente usam os seguintes mapeamentos para gerar caracteres de controle :

pressione a tecla ASCII
--------------------
ESCAPAR 27
EXCLUIR 127
RETROCESSO 8
CTRL+ESPAÇO 0
CTRL+@0
CTRL+A 1
CTRL+B2
CTRL+C3
etc...
CTRL+X 24
CTRL+Y 25
CTRL+Z 26
CTRL+[27
CTRL+\28
CTRL+] 29
CTRL + ^ 30
CTRL+_31

Observe que CTRL+; não aparece nessa lista. Os terminais geralmente enviam apenas o caractere imprimível atribuído achavese CTRL+chavenão está mapeado para um caractere de controle. Então, o que seu emulador de terminal está lhe dizendo ao enviar; por si só é que ele não sabe o que fazer quando você pressiona CTRL+;.

Tudo isso se aplica apenas se você estiver usando um terminal ou um programa de emulação de terminal. Se você estiver executando o Emacs como um aplicativo nativo em algum sistema de janelas, o Emacs terá acesso total aos eventos de pressionamento de tecla e não apenas aos caracteres. Assim, o Emacs pode ver que você pressionou CTRL e ponto e vírgula juntos e permite atribuir uma ação a esse par de teclas.

Os terminais geralmente possuem teclas de função e teclas de seta que também geram sequências de caracteres que incluem caracteres de controle. Essas sequências normalmente começam com o código ASCII 27 (ESCAPE).

Responder2

Os terminais transmitem caracteres (mais precisamente: bytes), não chaves. Quando você pressiona uma tecla ou um teclado como Ctrl+ ;, essa informação deve ser codificada em uma sequência de bytes. Keychords que representam um caractere, como Aou Shift+ Aou À, são enviados como esse caractere: a, A, à(sendo o último um ou dois bytes dependendo da codificação de caracteres do terminal).

Keychords envolvendo teclas de função não possuem caractere correspondente, portanto são enviados como sequências de escape: uma sequência de bytes começando com o caractere de escape ( \eem uma string Emacs, aparecendo como ciano ^[se inserido literalmente em um buffer). Algumas teclas de função possuem bytes correspondentes que sãopersonagens de controle.

O keychord Ctrl+ ;não possui sequência de escape padrão, então a maioria dos emuladores de terminal gera o caractere ;. Isso perde a informação de que o Ctrlmodificador foi pressionado.

Para definir uma ligação para Ctrl+ ;, você precisará configurar seu emulador de terminal para enviar uma sequência de escape diferente. Não acho que você possa fazer isso com o terminal Gnome (o Gnome raramente é configurável). Você pode fazer isso com o Xterm. VerExiste algum terminal Linux que possa lidar com todas as combinações de teclas?para obter instruções.

O shell que você pode executar no terminal não está envolvido. Uma GUI O Emacs não tem problema porque a GUI (X11) transmite eventos de entrada em uma forma que codifica chaves e modificadores, não como uma mera sequência de caracteres.

VerComo funcionam a entrada do teclado e a saída de texto?para obter informações mais detalhadas sobre como a entrada vai do teclado para o aplicativo.

informação relacionada