¿Por qué Emacs ejecutándose en una terminal no puede distinguir Ctrl+; de ";"?

¿Por qué Emacs ejecutándose en una terminal no puede distinguir Ctrl+; de ";"?

Esta pregunta surgió de mipregunta anterior sobre emacs beta. En resumen, quiero vincularme C-;a funciones de Emacs en una terminal, pero parece que algo captura esta tecla antes de que llegue a Emacs: Emacs cree que presioné ;.

El sospechoso obvio es el emulador de terminal, pero he comprobado muchos de ellos (xterm, gnome-terminal, terminator, terminología) y ninguno funciona. Lo más probable es que pueda excluir el administrador de ventanas, porque en la versión GUI de Emacs, la clave C-;funciona bien. También probé dos shells diferentes: bash y zsh, pero nuevamente sin éxito.

¿Qué más puedo probar?

Respuesta1

Quizás tu confusión surja por no haber utilizado un terminal real. Cuando las computadoras serias tenían el tamaño de varios refrigeradores verticales, unaTerminalSe comunica con una computadora central a través de un cable serie usando caracteres y caracteres únicamente. Los caracteres formaban parte de algún conjunto de caracteres estandarizado, por ejemplo, ASCII o EBCDIC, pero normalmente ASCII. ASCII tiene 33 caracteres de control y el operador del terminal los envió presionando una tecla especial (como DEL) o manteniendo presionada la tecla CTRL y presionando otra tecla. La computadora central sólo vio el carácter de control resultante; no sabía qué teclas se presionaron para producir el personaje.

Un programa de emulación de terminal como xterm imita ese comportamiento. El emulador de terminal proporciona una forma de enviar los 33 caracteres de control ASCII y Emacs recibirá esos caracteres si se envían. Pero Emacs es como la computadora central en la descripción anterior: no tiene forma de saber qué teclas se presionaron realmente cuando lo ejecuta en un emulador de terminal. Entonces, si presiona CTRL y punto y coma, a menos que el programa de emulación de terminal haya asignado esas pulsaciones de teclas a algún carácter ASCII, Emacs no sabrá que se ha escrito algo.

Los emuladores de terminal suelen utilizar las siguientes asignaciones para generar caracteres de control :

pulsación de tecla ASCII
--------------------
ESCAPAR 27
BORRAR 127
RETROCESO 8
CTRL+ESPACIO 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

Tenga en cuenta que CTRL+; no aparece en esa lista. Las terminales generalmente solo enviarán el carácter imprimible asignado allavesi CTRL+llaveno está asignado a un carácter de control. Entonces, ¿qué te dice tu emulador de terminal al enviar ; Lo único es que no sabe qué hacer cuando presiona CTRL+;.

Todo esto se aplica sólo si estás utilizando una terminal o un programa de emulación de terminal. Si está ejecutando Emacs como una aplicación nativa bajo algún sistema de ventanas, entonces Emacs tiene acceso completo a los eventos de pulsación de teclas y no solo a los caracteres. Entonces Emacs puede ver que presionó CTRL y punto y coma juntos y le permite asignar una acción a ese par de teclas.

Los terminales suelen tener teclas de función y teclas de flecha que también generan secuencias de caracteres que incluyen caracteres de control. Estas secuencias suelen comenzar con el código ASCII 27 (ESCAPE).

Respuesta2

Los terminales transmiten caracteres (más precisamente: bytes), no claves. Cuando presiona una tecla o un acorde como Ctrl+ ;, esta información debe codificarse en una secuencia de bytes. Los acordes clave que representan un carácter, como Ao Shift+ Ao À, se envían como ese carácter: a, A, à(el último es uno o dos bytes dependiendo de la codificación de caracteres del terminal).

Los acordes que involucran teclas de función no tienen ningún carácter correspondiente, por lo que se envían como secuencias de escape: una secuencia de bytes que comienza con el carácter de escape ( \een una cadena de Emacs, que aparece como cian ^[si se ingresa literalmente en un búfer). Algunas teclas de función tienen bytes correspondientes que sonpersonajes de control.

El acorde Ctrl+ ;no tiene una secuencia de escape estándar, por lo que la mayoría de los emuladores de terminal generan el carácter ;. Esto pierde la información de que Ctrlse presionó el modificador.

Para definir un enlace para Ctrl+ ;, deberá configurar su emulador de terminal para enviar una secuencia de escape diferente. No creo que puedas hacer esto con la terminal Gnome (Gnome rara vez se puede configurar). Puedes hacerlo con Xterm. Ver¿Existen terminales Linux que puedan manejar todas las combinaciones de teclas?para obtener instrucciones.

El shell que puede ejecutar en la terminal no está involucrado. Una GUI Emacs no tiene ningún problema porque la GUI (X11) transmite eventos de entrada en una forma que codifica claves y modificadores, no como una mera secuencia de caracteres.

Ver¿Cómo funcionan la entrada y salida de texto por teclado?para obtener información más detallada sobre cómo la entrada llega desde su teclado a su aplicación.

información relacionada