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

8

Esta pergunta surgiu da minha pergunta anterior sobre o emacs beta . Em suma, eu quero vincular C-; a uma função 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 eu verifiquei muitos deles (xterm, gnome-terminal, terminator, terminologia) e nenhum deles funciona. Muito provavelmente eu posso excluir o gerenciador de janelas, porque na versão GUI do Emacs, a chave C-; funciona muito bem. Eu tentei também duas shells diferentes: bash e zsh, mas novamente sem sucesso.

O que mais posso experimentar?

    
por WeSenseASoulInSearchOfAnswers 12.10.2014 / 18:58

2 respostas

11

Talvez sua confusão resulte de não ter usado um terminal real. Quando computadores sérios eram do tamanho de vários refrigeradores verticais, um terminal comunicava com um computador central através de um cabo serial usando apenas caracteres e caracteres. Os caracteres faziam parte de algum conjunto de caracteres padronizado, por ex. ASCII ou EBCDIC, mas normalmente ASCII. O ASCII possui 33 caracteres de controle e o operador do terminal os enviou pressionando uma tecla especial (como DEL) ou pressionando a tecla CTRL e pressionando outra tecla. O computador central só viu o caractere de controle resultante; não sabia quais teclas foram pressionadas para produzir o personagem.

Um programa de emulação de terminal, como 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 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 sob 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 esses pressionamentos de tecla 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 :

keypress       ASCII
--------------------
ESCAPE          27
DELETE          127
BACKSPACE       8
CTRL+SPACE      0
CTRL+@          0
CTRL+A          1
CTRL+B          2
CTRL+C          3
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 normalmente enviarão apenas o caractere imprimível atribuído à chave se a tecla CTRL + não estiver mapeada para um caractere de controle. Então, o que seu emulador de terminal está lhe dizendo enviando; sozinho é que ele não sabe o que fazer quando você pressiona CTRL +;.

Tudo isso se aplica somente 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. Então o Emacs pode ver que você pressionou CTRL e ponto-e-vírgula juntos e permite que você atribua 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 seqüências geralmente começam com o código ASCII 27 (ESCAPE).

    
por 12.10.2014 / 20:33
3

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

Os teclados que envolvem teclas de função não têm caracteres correspondentes, sendo enviados como sequências de escape: uma sequência de bytes começando com o caractere de escape ( \e em uma string do Emacs, aparecendo como ciano ^[ se inserido literalmente em um buffer ). Algumas teclas de função têm bytes correspondentes que são caracteres de controle .

O teclado Ctrl + ; não possui uma seqüência de escape padrão, portanto a maioria dos emuladores de terminal geram o caractere ; . Isso perde a informação que o modificador Ctrl foi pressionado.

Para definir uma ligação para Ctrl + ; , você precisará configurar seu emulador de terminal para enviar uma seqüência de escape diferente. Eu não acho que você pode fazer isso com o terminal Gnome (o Gnome raramente é configurável). Você pode fazer isso com o Xterm. Veja Existe alguma terminais linux que podem lidar com todas as combinações de teclas? para instruções.

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

Veja Como a entrada e o texto do teclado trabalho de saída? para informações mais detalhadas sobre como a entrada vai do seu teclado para o seu aplicativo.

    
por 13.10.2014 / 01:01