Las teclas del cursor son divertidas.

Las teclas del cursor son divertidas.

Utilizo el shell zsh como shell predeterminado tanto en Ubuntu como en Arch.

Configuré un acceso directo (la flecha hacia arriba) para autocompletar desde el historial en mi shell zsh, usando la siguiente línea en mi .zshrc:

bindkey "^[[A" history-beginning-search-backward

Sin embargo, cuando obtengo mi.zshrc y/o reinicio en Ubuntu, el acceso directo no funciona (solo obtengo el comando anterior, sin importar lo que comencé a escribir), mientras que en Arch funciona bien (solo obtengo el último comando que comienza con lo que Escribí).

Alguien sabe cómo resolver esto?

Respuesta1

En la mayoría de terminales tipo xterm, Up(y es similar para la mayoría de las teclas de navegación) envían␛[A o ␛OAdependiendo de si el terminal se ha instaladotransmisión del tecladomodo o no. Las entradas smkxy rmkxterminfo se pueden utilizar para poner un terminal dentro o fuera de ese modo.

La kcuu1entrada terminfo (cursor de tecla arriba en 1) describe la secuencia enviada porUp cuando está entransmisión del tecladomodo, eso es ␛OA.

Debian y derivados tienen un /etc/zsh/zshrcarchivo que hace un

function zle-line-init () {
   emulate -L zsh
   printf > /dev/tty '%s' ${terminfo[smkx]}
}

Lo que pone al terminal en ese modo cuando zle está activo, lo que significa que ahora puede confiar en la base de datos terminfo para saber qué secuencias de caracteres transmiten las claves.

El archivo tambiéndefine un$key matriz asociativabasado en las entradas de terminfo para ayudarlo a asignarlas a los widgets. Entonces, en esos sistemas, puedes hacer:

(($+key[Up])) && bindkey $key[Up] history-beginning-search-backward

Para algo que funciona en sistemas donde está el terminaltransmisión del tecladomodo y los que no tienen o no tienen el $keyhash, puedes hacer:

bindkey $terminfo[kcuu1] history-beginning-search-backward
bindkey ${terminfo[kcuu1]/O/[} history-beginning-search-backward

Ver también:

Respuesta2

Las teclas del cursor son divertidas.

Aunque no son tan divertidos como las teclas de edición, que sonen realidaddivertido.

Tienesdos conjuntosde las teclas del cursor en su teclado, las delteclado de cursory los delteclado de la calculadora.

La mayoría de los emuladores de terminales intentan (a veces bastante mal) emplear el modelo de DEC VT, donde cada conjunto de teclas se puede conmutar individualmente entremodo de aplicaciónymodo normalusando la configuración del modo privado DECCKM(modo de teclado cursor) y DECNKM(modo de teclado numérico), respectivamente. La idea del modo de aplicación es esencialmente que las teclas del teclado correspondiente se conviertan en teclas de función de aplicación adicionales.

⇐ Este es el teclado del cursor.
  • En modo normal, las teclas de flecha envían las secuencias ECMA-48 CUB, CUF, CUUy de control, a menos que el modificador esté vigente, en cuyo caso envíanCUD⎇ AltDECFNK secuencias de control.
  • En el modo de aplicación, las teclas de flecha envían SS33 secuencias de un solo turno.
⇐ Este es el teclado de la calculadora.
  • En modo normal, las teclas de flecha envían las secuencias ECMA-48 CUB, CUF, CUUy de control, a menos que el modificador esté vigente, en cuyo caso envíanCUD⎇ AltDECFNK secuencias de control, o a menos que la combinación de bloqueo numérico y mayúsculas haga que envíen dígitos.
  • En el modo de aplicación, las teclas de flecha envíanun conjunto diferente de SS3secuencias de un solo turno 3 (a menos que, nuevamente, la combinación de bloqueo numérico y cambio haga que envíen dígitos).

La [ Asecuencia que le ha indicado a ZLE que se vincule a un widget es un alias ECMA-48 de 7 bits para la CSI Asecuencia de control, que es la CUPsecuencia de control ("Cursor ARRIBA"). Esa secuencia de control solo la generan los DEC VT y sus emuladores de terminales imitadores cuando un teclado está en modo normal y el ⎇ Altmodificador no está en efecto. No coincidirá con las secuencias de turnos enviadas cuando los teclados relevantes estén en modo de aplicación.

La base de datos terminfo enturbia las aguas y causa más diversión aquí, porque no emplea este modelo para E/S de terminal. Más bien, emplea su propiadiferentemodelo que incorpora nociones de teclas "locales" y "remotas", que no es lo que realmente implica el cambio de aplicación/modo normal de DEC VT; y tiene un único mecanismo de conmutación local/remoto, que termina conmutandoambosteclados entre los modos aplicación/normal de forma indivisible.

terminfo es la forma de no cablear a un tipo de terminal específico mientras configura ZLE, en caso de que se encuentre con un terminal o emulador de terminal que no imite un DEC VT. Y el shell Z le proporciona formas de acceder a las entradas de capacidad necesarias desde el registro de la base de datos. Por lo tanto, puede leer en terminfo qué secuencias de control espera terminfo que produzcan las teclas de cursor arriba/abajo/izquierda/derecha y emitir bindkeylos comandos apropiados que asignan esas secuencias de control a los widgets.

El problema es que terminfo no es adecuado para este trabajo. Solo tiene forma de grabarunosecuencia de control por tecla, mientras que, como puede ver, las teclas pueden enviaral menosTres secuencias diferentes, dependiendo del modo y modificadores presionados. (Los modificadores pueden influir significativamente en las secuencias de control enviadas en el modelo DEC VT). Por lo tanto, debe cambiar el terminal al modo que genera lo que terminfo le indica que espere.

Pero se pone peor: terminfo no es consistente. La secuencia de control única es a veces la secuencia del modo de aplicación DEC VT, como registros terminfo paraelputty tipo de terminal, a veces la secuencia del modo normal DEC VT, como registros terminfo paraelrxvt tipo de terminal, pero nunca la DECFNKsecuencia. Por lo tanto, no tiene forma de saber si debe cambiar a la aplicación o al modo normal con cualquier terminal o emulador de terminal. Lo que funcionará bien para uno, saldrá mal para otro.

El otro enfoque, por lo tanto, es ignorar terminfo y darse cuenta de que estáyay asumiendo muy felizmente que tu terminal siempre va a ser como un DEC VT con tu originalbindkey comando original. Sólo necesitas dos de ellos, para asegurarte de que tanto si tu terminal está en modo aplicación como normal la secuencia de control que envía coincidirá:

bindkey "^[OA" historial-comienzo-búsqueda-hacia atrás

Sin embargo, esto no funcionará cuando se presionen las teclas modificadoras, lo que agrega parámetros adicionales a la CUPsecuencia de control que causa que la coincidencia de cadenas simplista que utiliza ZLE falle cuando todo lo que está buscando es simple y antiguo sin parámetros CUP. Debe emitir manualmente un bindkeycomando adicional para cada posible CUPsecuencia de control resultante de cada posible combinación de modificadores.

secuencia 1 8 |
mientras lee -ri
hacer
    bindkey "^[[1;${i}A" historial-comienzo-búsqueda-hacia atrás
hecho

ZLE no está solo aquí. Otros programas basados ​​en terminfo, como el fishshell, sufren de la misma manera. (La fishgente del shell también descubrió que la opción de aplicación/modo normal que funciona bien para un emulador de terminal funcionará mal para otro).libtermkeyque tiene un analizador de secuencia de control ECMA-48 real como entrada) en estos programas hace tiempo que debería haberse implementado. Pero nadie lo ha abordado todavía.

Otras lecturas

información relacionada