¿Cómo detengo la grabación mientras estoy en la línea de comando?

19

Cuando estoy grabando una macro con qy he terminado, puedo escribir:

  • q para detener la grabación si estoy en modo normal o visual.
  • <c-o>q para detener la grabación si estoy en modo de inserción.
  • ..

    ¿Cómo detengo la grabación si mi macro termina en modo comando?

iago-lito
fuente
¿Cuál es su caso de uso para esto? Tengo curiosidad :)
PhilippFrank
2
@PhilippFrank Frecuentemente buscaré y reemplazaré el mismo patrón con diferentes en varios bloques de texto. Con dicha macro, se puede seleccionar automáticamente el bloque, escribir el patrón de búsqueda real y colocar el cursor en la posición correcta para escribir la cadena de reemplazo. Cuando lo juegue, seleccionará el bloque, entrará en modo comando, escribirá y :'<,'>s/toBeReplaced//gluego colocará el cursor entre los dos //para que todo lo que tenga que hacer sea escribir newString<cr>y listo. :)
iago-lito
Entonces es como una macro con un parámetro. Muy buena idea, gracias!
PhilippFrank
@PhilippFrank tipo de, sí. Me alegro de que te guste. :)
iago-lito

Respuestas:

12

Otra solución es cuando está en modo de línea de comando, use Ctrl-fy presione qpara detener la grabación.

Ctrl-fle permite abrir la ventana de la línea de comandos, en la que puede editar el comando en modo normal. Para validar el comando, simplemente use enter.


Por lo tanto, después de haber agregado algo como:

cnoremap <c-q> <c-f>i<c-o>q

en su .vimrc, puede usar <c-q>para detener la grabación de una macro mientras está en modo comando.


Florent

fflorent
fuente
Todavía tiene que eliminar el carácter <Cf> ( ^F) del final de la macro, ¿verdad? Al menos eso es lo que veo.
VanLaser
¡Casi ahí! Realmente útil (no sabía sobre la ventana de la línea de comandos pero es genial), pero ... ¡aargh! Parece que al ingresar a esta ventana desde el modo de inserción, se pierde el área seleccionada. ¿Hay alguna manera de hacer que el comando que ejecute desde la ventana de la línea de comando funcione en un área seleccionada?
iago-lito
@VanLaser No, ya que puedes seguir escribiendo tu comando en la ventana de la línea de comandos. Su macro será similar qqSTARTMACRO:STARTCOMMANDLINEPART<c-f>i<c-o>qy, por lo tanto, la grabación se ha detenido mientras escribía la parte del comando. Para usar la macro: @qFINISHYOURCOMMAND<cr>y listo: no es necesario editarlo. Desafortunadamente, esto no parece funcionar desde el modo visual (o pierde la selección) ... ¿o me he perdido algo?
iago-lito
Ah, cierto :) Por cierto, podría seleccionar un rango visual, luego hacer @qy el rango se agregó al inicio del comando '<,'>, siempre que la macro comenzara con :...
VanLaser
@ lago-lito En realidad, parece que incluso si no ve su selección, el rango especificado (es decir '<,'>) todavía coincide con la selección al validar el comando.
fflorent
17

Una forma de hacerlo:

  • inicie su macro como de costumbre (por ejemplo, qqotros caracteres)
  • cuando llegue al modo cmdline, escriba todos los caracteres que desee
  • quieres terminar la macro aquí. Hit ESCsalir de línea_de_órdenes modo, qpara poner fin a su macro.
  • eliminar el ESCde su qregistro (*): puede pegarlo en un búfer, eliminar el ^[carácter, seleccionar todo el material nuevamente (en cuanto al carácter) y tirarlo de nuevo para registrarlo q.
  • eso es todo: ejecutar la macro: @q.

Básicamente, "procesas" un poco tu macro, ya que está almacenada en un registro :)

(*) Una forma rápida de eliminar el último carácter de una macro almacenada en el registro qsería:

:let @q = @q[:-2]
VanLaser
fuente
¡Jaja! Este ha sido mi truco hasta ahora = D. ¿No hay una forma "canónica" de hacerlo? (también más rápido )
iago-lito
No conozco una, pero no uso demasiado las macros (prefiero escribir funciones pequeñas). Las macros me parecen crípticas cuando las miro después.
VanLaser
@VanLaser: ¿podría dar un poco más de detalles sobre la línea, :let @q = @q[:-2]por favor? ¿Especialmente cómo [:-2]funciona? :-)
statox
Es "rebanar" y funciona en listas y cadenas (que es como accedo / configuro @qarriba). Algunos ejemplos aquí
VanLaser
@VanLaser realmente se ven crípticos. Sin embargo, son útiles para repetir pequeñas cosas sofisticadas que necesitas hacer en casos muy específicos ... conoces este tipo de problemas que aparecen solo una vez y solo duran unos minutos. Ser capaz de lidiar con ellos creando macros sobre la marcha y sin tener que escribir y depurar una función dedicada es simplemente ... ¡qué maravilla! ^ ^
iago-lito
3

Después de leer su comentario sobre el caso de uso, parece que podría usar una asignación de teclas en lugar de una macro.

Tengo esta línea en mi .vimrc (no recuerdo dónde la encontré):

nnoremap <Leader>s :%s/\<<C-r><C-w>\>//g<Left><Left>

Tiene un efecto similar al caso de uso que describió, colocándolo en la línea de comando, por lo que lo único que debe hacer es escribir el reemplazo y presionar enter, pero en este caso, reemplazar todas las apariciones de la palabra que estaba debajo de su cursor .

Para reemplazar dentro del bloque actual, creo que algo como lo siguiente debería funcionar:

nnoremap <Leader>s m'va{<ESC>``:'<,'>s/\<<C-r><C-w>\>//g<Left><Left>

Por supuesto, puede asignarlo a la clave que desee.

Lo que hace lo anterior: marca la posición actual usando el marcador sin nombre, selecciona visualmente el bloque actual, abandona el modo visual y regresa el cursor a la posición guardada (los marcadores de selección visual todavía están configurados), ingresa al modo de comando y escribe el comando sustituto , insertando la palabra que estaba debajo del cursor con <C-r><C-w>y colocando el cursor para escribir el reemplazo.

dhakimian
fuente
Sí, yo también tengo este. Sin embargo, en mi caso de uso específico, el toBeReplacedpatrón no es tan simple como "la palabra debajo del cursor", por lo que necesito una macro pequeña y específica que podría crear sobre la marcha. Y de nuevo: demasiado específico para un mapa: \ Gracias de todos modos :)
iago-lito
2
Tal vez, coloque el patrón en un registro, luego adapte la asignación anterior para obtener automáticamente el contenido del registro como toBeReplacedparte (en lugar de la palabra actual debajo del cursor, lo cual es más limitante).
VanLaser
1
@VanLaser Right, eso permitiría un mapeo general, y también lo haría mucho más simple: va{:s/<C-r>0//g<Left><Left>con esto puede tirar de antemano cualquier patrón que necesite de antemano, y luego simplemente presionar la tecla asignada para reemplazar ese patrón con algo en el actual bloquear.
dhakimian