Vim: Cómo manejar los saltos de línea al almacenar múltiples comandos en los registros?

StackOverflow https://stackoverflow.com/questions/2730922

  •  02-10-2019
  •  | 
  •  

Pregunta

Tengo un archivo donde almaceno fragmentos de comandos de vim. Cuando necesito un fragmento, me tire de éste y luego ejecutarlo con @". Los fragmentos se almacenan como un guión, una línea por cada comando, así:

:s/foo/bar/g
:echo "hello"
:s/1/2/g

Edit: I eliminó comandos modo normal desde el ejemplo, ya que no eran parte del problema

.

Ahora bien, este procedimiento no funciona más: cuando se ejecuta el fragmento, que sólo se detiene en la primera línea como si estuviera esperando una nueva línea.

¿Hay algún lugar una opción que afecta a cómo se ejecuta @? Estoy bastante seguro de que estaba trabajando hace algún tiempo ...

La sustitución de la nueva línea con un carácter ^ M obras, pero hace que el archivo más difíciles de manejar.


Información adicional:

Este es otro síntoma: cuando un tirón un fragmento, si ejecuto con @" se detiene en la primera línea como acabo de explicar. Pero si ejecuto con :@ funciona. Sin embargo, el archivo de ayuda no parece implicar ninguna diferencia en cómo los dos comandos procesan el contenido del registro ...

¿Fue útil?

Solución 2

Finalmente encontré el culpable. De alguna manera tuve un mapeo de comandos en <C-J> en mi archivo .vimrc. Cuando se lee con la cpoptions por defecto, esto se convirtió en un mapeo de <NL>.

¿Cómo descubrí: Me di cuenta de que al iniciar Vim con -u ~/.vimrc, que de hecho se ejecutaría fragmentos arrancados. Me genera un archivo de sesión con y sin la opción de línea de comandos y los compararon. De esta manera descubrí que un conjunto diferente de donde cpoptions utiliza para leer el mismo archivo .vimrc, de manera que en un caso el mapeo fue hecho en <C-J>, en el otro se convirtió en un mapeo de <NL>!

Si alguien tiene un problema similar, yo sugeriría mirar cuidadosamente las asignaciones de comandos establecidos actualmente, con :cmap.

Otros consejos

No creo que el problema es ^M vs ^J. macros Vim tratar cualquiera de los dos como un carácter válido de final de línea para las macros grabadas. Creo que el problema es nuevas líneas adicionales.

En el ejemplo, hay por lo menos un salto de línea después espuria 2j, ya menos que seas un cuidado especial cuando se copia el fragmento, es probable que haya una tras otra 10k también. Estas nuevas líneas adicionales son como presionar <Enter> en modo normal -. Mueven el cursor una línea hacia abajo

Esto es lo que creo que quiere que el fragmento de aspecto:

:s/foo/bar/g
2j:s/1/2/g
10k

(Incluso eso es un poco engañoso -. Todavía habría que tener cuidado de no copiar el salto de línea después de la 10k)

¿Por qué estas nuevas líneas adicionales hacen una diferencia tan grande? Bueno, por un lado, que te entregará al menos una línea de distancia de donde se espera que sea, que se despoja de todo lo que quiere hacer en una línea particular (como ejecutar el comando :s//).

Más importante, sin embargo - y esto es lo que creo que está sucediendo en su ejemplo - es que Vim se detiene la reproducción de macro si la macro intenta uso <Enter> en la última línea de un tampón. (Supongo que Vim considera que es un error, y cualquier error hace que una macro para detener la ejecución.)

Este es un ejemplo. Supongamos que tienes este fragmento almacenado en el registro X:

4j
:echo "Done"

(Aviso de la nueva línea después de 4j.)

Además, suponga que tiene los siguientes cinco líneas (y sólo estas cinco líneas) en un tampón:

line 1
line 2
line 3
line 4
line 5

Si ahora presiona @x en line 1, la :echo "Done" nunca se ejecuta. Vim mueve el cursor hacia abajo 4 líneas a line 5, a continuación, intenta mover una línea hacia abajo más a causa de la nueva línea extra, pero no puede. Los macro se detiene la ejecución en ese momento, antes de que el comando :echo tiene la oportunidad de funcionar.

Sin embargo, funciona si se cambia la x registrarse para esto:

4j:echo "Done"

Así que para volver a su original ejemplo, apuesto lo que está sucediendo es que el salto de línea extra después de 2j está intentando mover el cursor en algún lugar que no puede ir, y que hace que la macro a la parada. La línea inferior de la pantalla contiene el último comando ejecutado (:s/foo/bar/g), lo que hace que parezca que Vim está esperando a que presione Retorno.

Por último, me gustaría recomendar encarecidamente el uso de otro método para almacenar y ejecutar secuencias de comandos de Vim. La técnica que utiliza es tolerable para los casos simples, pero es frágil y no escala bien. Vim tiene un lenguaje de programación completo que incluye las funciones y comandos personalizados, y puede ser utilizado para hacer todas las cosas que estás haciendo ahora, pero de una manera mucho más robusta. secuencias de comandos Vim es un gran tema, pero me gustaría empezar aquí:

:help script

Asegúrese de leer sobre el comando :normal, que le permite ejecutar comandos en modo normal (como 2j y 10k) dentro de las secuencias de comandos.

Buena suerte!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top