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 ( \e
em 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.