Ctrl-Retroceso y Ctrl-Delete en bash

14

Poner en Debian 8.3

stty werase '^H'

o en Arch Linux 2/2016

stty werase '^?'

en .bashrc(por ejemplo) marcas Ctrl: Backspaceelimina la última palabra en el terminal. Aún no es el mismo comportamiento que en las aplicaciones GUI modernos (por ejemplo Firefox): Borra el último espacio en blanco palabra Separado, y no la última palabra separados por espacios en blanco o caracteres como . : , ; " ' & / ( ).

¿Es posible hacer que Ctrl- Backspacese comportan en el terminal similar a las aplicaciones GUI modernas? Además, ¿hay alguna forma de hacerlo Ctrl: Deleteeliminar la palabra inmediatamente antes del cursor?

gatos lobo-revo
fuente
1
Su shell podría admitir esas acciones, que podrían estar vinculadas a una clave determinada.
Thomas Dickey
@ThomasDickey: estoy usando bash. Está bien si funciona solo en bash.
wolf-revo-cats

Respuestas:

27

Aquí hay dos editores de línea en juego: el editor de línea básico proporcionado por el núcleo (editor de línea tty en modo canónico) y el editor de línea de bash (implementado a través de la biblioteca readline). Ambos tienen un comando de borrar a la palabra anterior que está vinculado a Ctrl+ Wpor defecto. La clave se puede configurar para el editor de línea tty en modo canónico a través de stty werase; bash imita el enlace de teclas que encuentra en la configuración tty a menos que se anule en su propia configuración.

La weraseacción en el editor de líneas tty no se puede configurar. Siempre borra (ASCII) palabras delimitadas por espacios en blanco. Es raro interactuar con el editor de líneas tty: es lo que obtienes, por ejemplo, cuando escribes catsin argumento. Si desea combinaciones de teclas sofisticadas allí, puede ejecutar el comando bajo una herramienta como rlwrap que usa readline.

Bash proporciona dos comandos para eliminar la palabra anterior : unix-word-rubout( Ctrl+ wo según lo establecido stty werase), y backward-kill-word( M-DEL, es decir, Esc Backspace) que trata una palabra como una secuencia de caracteres alfanuméricos en la configuración regional actual y_ . Si desea Ctrl+ Backspacepara borrar la secuencia anterior de caracteres alfanuméricos, no establezca stty werasey, en su lugar, coloque la siguiente línea en su .inputrc:

"\C-h": backward-kill-word

Tenga en cuenta que esto supone que su terminal envía el carácter Ctrl + H para Ctrl+ Backspace. Desafortunadamente, es una de esas claves sin enlace estándar (y Backspaceen particular es un desastre por razones históricas).

También hay un comando simétrico kill-wordque está vinculado a M-d( Alt+ D) de forma predeterminada. Para vincularlo a Ctrl+ Delete, primero debe averiguar qué secuencia de escape envía su terminal, luego agregar una línea correspondiente en su .inputrc. Escriba Ctrl+ Vluego Ctrl+ Delete; esto insertará algo como ^[[3;5~donde la inicial ^[es una representación visual del carácter de escape. Entonces la unión es

"\e[3;5~": kill-word

Si no está satisfecho con cualquiera de las definiciones de una palabra, puede proporcionar la suya propia en bash: vea el comportamiento confuso de las combinaciones de teclas de estilo emacs en bash

Gilles 'SO- deja de ser malvado'
fuente
2
excelente explicación! El Ctrl+Delfuncionó bien. Sin embargo, no puedo ir Ctrl+Backspacea trabajar. Para Ctrl+v, Ctrl+Backspacemi terminal dice ^?. ¿Qué debo poner en el .inputrc? Gracias
Ciprian Tomoiagă
3
@CiprianTomoiaga "\C-?": backward-kill-wordo cualquier función de línea de lectura que desee. Pero solo puede definir un enlace para Ctrl + Retroceso que sea diferente del enlace para Retroceso si envían caracteres diferentes. Si su terminal envía ^?tanto Retroceso como Ctrl + Retroceso, la aplicación que se ejecuta en el terminal no tiene forma de distinguirlos. Algunos terminales se pueden configurar (por ejemplo, xterm, urxvt), otros (por ejemplo, emuladores de terminales basados ​​en VTE) no.
Gilles 'SO- deja de ser malvado'
44
Es importante tener en cuenta que la definición ~/.inputrcdeshabilita el valor predeterminado /etc/inputrc. para solucionar esto, debe incluir ese archivo: $include /etc/inputrc(desde aquí )
Ciprian Tomoiagă
+1 para Esc + Retroceso
Celal Ergün
6

Tratar

alt+backspace

En el sistema operativo primario funciona como lo desea (como ctrl+ backspace)

Ahmed Elkoussy
fuente
1

El comportamiento del carácter WERASE en el procesamiento de terminal en modo cocinado está codificado , al menos en Linux:

           if (kill_type == WERASE) {
                   /* Equivalent to BSD's ALTWERASE. */
                   if (isalnum(c) || c == '_')
                           seen_alnums++;
                   else if (seen_alnums)
                           break;
           }

Entonces las palabras son letras, dígitos y guiones bajos. Esta es la forma en que siempre estará en un terminal en Linux cuando una aplicación que realiza su propio procesamiento en modo cocinado no se está ejecutando.

La versión de readline (utilizada por bash y otros) parece ser un poco diferente a la versión del núcleo, pero también parece estar codificada :

Las palabras están compuestas de letras y dígitos.

Pero esto no parece coincidir con lo que bashrealmente hace por mí: foo+bar^Wborra todo, no solo bar. Hay más información sobre eso aquí .

Celada
fuente
1. El usuario vi probablemente solo esté buscando backward-kill-word(enlace predeterminado M-DEL) en lugar de unix-word-rubout.
Gilles 'SO- deja de ser malvado'