readline: diferencia entre vi, vi-move, vi-command, vi-insert keymaps

7

La página de manual de readline (3) enumera estos cuatro (vi, vi-move, vi-command, vi-insert) como posibles opciones para la keymapconfiguración. He intentado configurar estas diferentes opciones y parecen no tener ningún efecto más allá de lo que set editing-mode vihace.

Probablemente la forma más sucinta de responder a esta pregunta es dar un ejemplo de cómo los cambios keymapmarcan la diferencia.

Cita de la página de manual:

keymap (emacs)
          Set the current readline keymap.  The set of legal keymap  names
          is  emacs,  emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
          vi-command, and vi-insert.   vi  is  equivalent  to  vi-command;
          <<snip>>
chisophugis
fuente
¿Alguien sabe qué es vi-move?
Oscar Korz
1
Es otro nombre para vi-commando vi... mira mi respuesta como prueba :)
Tom Hale

Respuestas:

2

Son los diferentes mapas de teclas dentro del modo vi. Por ejemplo, mis .inputrcconjuntos keymappara vincular teclas en diferentes modos. Extracto:

# insert mode bindings
set keymap vi-insert
"\C-p": previous-history
"\C-n": next-history

# command mode bindings
set keymap vi-command
"|": beginning-of-line
"_": vi-first-print
peth
fuente
3

TL; DR

Si quieres la esencia, salta al encabezado editing-mode vi(el último).

¡Pero espera! Sin embargo, es posible que se necesite bastante información de fondo: por ejemplo, la diferencia entre an editing-modey a keymap.

Particularmente útil es el concepto de un emacsmapa de teclas híbrido para insertar texto y al mismo tiempo acceder fácilmente vi-commandpara realizar cambios.

¿Cuál es la diferencia entre an editing-modey a keymap?

Hay solamente dos editing-modes: emacs(por defecto) y vi.

La documentación de GNU Readline Library dice:

editing-mode
    The editing-mode variable controls which default set of key bindings is
    used. By default, Readline starts up in Emacs editing mode, where the
    keystrokes are most similar to Emacs. This variable can be set to either
    `emacs' or `vi'.

Tenga en cuenta la diferencia entre editing-modey keymap: en editing-mode vilos dos (sí, solo hay dos, siga leyendo) los mapas de teclas se intercambian para emular los diferentes modos del vieditor. TODOS los emacsque operan al mismo tiempo en editing-mode emacs(explicado más adelante).

Entonces, ¿qué hace editing-moderealmente? Simplemente establece el mapa de teclas activo al iniciar el shell en emacso vi-insert.

¿Cuáles son los mapas de teclas únicos?

Acceptable keymap names are emacs, emacs-standard, emacs-meta, emacs-ctlx,
vi, vi-move, vi-command, and vi-insert.

vi is equivalent to vi-command; emacs is equivalent to emacs-standard.

Si bien no está documentado, vi/ vi-commandy los vi-movemapas de teclas también son equivalentes:

+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$ 

Esto nos deja con: emacs, emacs-meta, emacs-ctlx, vi, y vi-insertcomo mapas de teclas exclusivas para explicar. Probablemente lo mejor sea diferenciar los mapas de teclas inspeccionándolos ...

¿Cuáles son los enlaces predeterminados de los mapas de teclado?

Para ver las combinaciones de teclas predeterminadas para (por ejemplo) emacs (el predeterminado), use:

INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -v '^#

Puede reemplazarlo emacscon cualquier otro nombre de mapa de teclas en el ejemplo anterior.

Hay muchas líneas que dicen self-inserto do-lowercase-versionque no son muy útiles, así que para eliminarlas:

INPUTRC=~/dev/null bash -c 'bind -pm emacs' | grep -vE '^#|: (do-lowercase-version|self-insert)$' | sort

¿Cuál es la diferencia entre los distintos emacsmapas de teclas?

TL; DR: son vistas diferentes en un solo conjunto de asignaciones aplicadas editing-mode emacs.

Si la salida del segundo comando en los archivos de llamada emacs-standard, emacs-meta, emacs-ctlx, vi-command, y vi-insertpor sus correspondientes keymaps, se puede descubrir que:

NO hay comandos asignados emacs-metay emacs-ctlxque tampoco aparecen en emacs-standard:

$ comm -13 <(sed -r 's/.*: (\S+)/\1/' emacs-standard|sort) <(sed -r 's/.*: (\S+)/\1/' emacs-ctlx|sort)
$ comm -13 <(sed -r 's/.*: (\S+)/\1/' emacs-standard|sort) <(sed -r 's/.*: (\S+)/\1/' emacs-meta|sort)
$

Entonces emacs/ emacs-standardes un superconjunto funcionalmente funcional de ambos emacs-ctlxy emacs-metaesto significa que:

keymap emacs
"\eg": glob-expand-word
"\C-x\C-r": re-read-init-file

Es funcionalmente equivalente a:

keymap emacs-meta
"g": glob-expand-word

keymap emacs-ctlx
"\C-r": re-read-init-file

Podría argumentar que la segunda forma es más fácil de leer.

Insertar texto: emacsvsvi-insert

Hay 28 comandos en emacs-standardno envi-insert

+ravi@boxy:~/lib/readline$ comm -12 vi-insert emacs-standard |wc -l
28
+ravi@boxy:~/lib/readline$

emacs/ emacs-standardes básicamente un superconjunto de vi-insert. Por lo tanto, para escribir texto, es mejor usar el emacs-standardmapa de teclas vi-insertsiempre que pueda cambiar fácilmente entre emacsyvi-command .

Los únicos enlaces adicionales en vi-insertnot in emacs-standardson:

+ravi@boxy:~/lib/readline$ comm -23 vi-insert emacs-standard 
"\C-d": vi-eof-maybe
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\e": vi-movement-mode

Los primeros 3 de estos cuatro conflictos con los emacsenlaces:

"\C-d": delete-char
"\C-n": next-history
"\C-p": previous-history

que resolví de la siguiente manera:

set keymap emacs
"\e": "kj" # see https://unix.stackexchange.com/questions/303631/how-can-i-setup-a-hybrid-readline-with-emacs-insert-mode-and-vi-command-mode
"\C-d": delete-char # eof-maybe: ^D does nothing if there is text on the line
"\C-n": menu-complete
"\C-p": menu-complete-backward
"\C-y": previous-history # historY
"\e\C-y": previous-history

editing-mode vi

Como hemos visto más arriba, vi, vi-commandy vi-moveson uno y el mismo mapa de teclas:

+ravi@boxy:~$ diff <(bind -pm vi) <(bind -pm vi-move)
+ravi@boxy:~$ 

Tenga en cuenta que se trata de un total de solo dos mapas distintos que están asociados por defecto editing-mode vi.

Cuando está en editing-mode vi, los keymaps en uso son vi/ vi-command/ vi-movey vi-insert(el mapa de teclas inicial). Solo uno de estos dos mapas está activo a la vez.

editing-mode vino hace nada más que establecer un mapa de teclas predeterminado cuando se inicia el shell, etiquetado vi-insert. De nuevo, solo hay un mapa de teclas activo a la vez. Este vi-insertmapa de teclas asigna la mayoría de las teclas de self-insertmodo que cuando presiona el botón de plástico en su teclado, el símbolo impreso aparece en su pantalla.

El vi-insertmapa de teclas se permite cambiar al mapa de teclas manipulador de texto llamado vi-command/ vi/ vi-movemediante el vi-movement-modecomando, vinculado a la ESCtecla de forma predeterminada en el vi-insertmapa de teclas .

En realidad, incluso el emacsmapa de teclas puede activar el vimapa de teclas de manipulación de texto similar mediante el vi-movement-modecomando, como en la solución híbrida mencionada anteriormente.

O en un lenguaje más fácil ...

De forma predeterminada, presione ESCpara cambiar al vi-commandmapa de teclas cuando el vi-insertmapa de teclas esté activo.

El vi-commandmapa de teclas utiliza pulsaciones de teclas estándar, simples a, by cpara moverse e interactuar con el texto, al igual que el vimodo predeterminado o de comando del editor. Generalmente no hay combinaciones Ctrl+ key. No puede insertar texto en este modo; las teclas de letras se asignan a comandos de edición / movimiento. Para escribir texto, cambie al vi-insertmapa de teclas (ejemplo: presione ipara "Insertar").

El ingreso de texto se realiza utilizando el vi-insertmapa de teclas, que está activo cuando se inicia el shell si tiene editing-mode vien su .inputrcarchivo. Cambie al vi-insertmapa de teclas presionando i"insertar" mientras está en vi-command(o de muchas otras maneras para aquellos iniciados en vi).

A menos que conozca el vieditor, es probable que encuentre vi-commandclaves muy difíciles de usar al principio, pero si lo hace bien, puede editar el texto como un asistente de barba larga.

Tom Hale
fuente