Vim: inserta los mismos caracteres en varias líneas

306

A veces quiero editar un cierto bloque visual de texto en varias líneas.

Por ejemplo, tomaría un texto que se ve así:

name
comment
phone
email

Y haz que se vea así

vendor_name
vendor_comment
vendor_phone
vendor_email

Actualmente la forma en que lo haría ahora es ...

  1. Seleccione las 4 líneas de fila de un bloque presionando Vy luego jcuatro veces.
  2. Sangría con >.
  3. Regrese una carta con h.
  4. Ir a bloquear el modo visual con Ctrlv.
  5. Seleccione hacia abajo cuatro filas presionando jcuatro veces. En este punto, ha seleccionado un bloque visual de espacios en blanco de 4x1 (cuatro filas y una columna).
  6. Presione C. Observe esto prácticamente sangrado a la izquierda por una columna.
  7. Escriba un " vendor_"sin la cita. Observe el espacio extra que tuvimos que volver a poner.
  8. Presione Esc. Esta es una de las pocas veces que uso Escpara salir del modo de inserción. Ctrlcsolo editaría la primera línea.
  9. Repita el paso 1.
  10. Sangrar a la inversa con <.

No necesito sangrar si hay al menos una columna de espacio en blanco antes de las palabras. No necesitaría el espacio en blanco si no tuviera que borrar el bloque visual c.

Pero si tengo que borrar, ¿hay alguna forma de hacer lo que realicé anteriormente sin crear el espacio en blanco necesario con sangría?

Además, ¿por qué la edición de varias líneas a la vez solo funciona al salir del modo de inserción con Escover Ctrlc?


Aquí hay un ejemplo más complicado:

name    = models.CharField( max_length = 135 )
comment = models.TextField( blank = True )
phone   = models.CharField( max_length = 135, blank = True )
email   = models.EmailField( blank = True )

a

name    = models.whatever.CharField( max_length = 135 )
comment = models.whatever.TextField( blank = True )
phone   = models.whatever.CharField( max_length = 135, blank = True )
email   = models.whatever.EmailField( blank = True )

En este ejemplo, realizaría el bloqueo visual vertical sobre el ., y luego lo volvería a insertar durante el modo de inserción, es decir, tipo .whatever.. Esperemos que ahora pueda ver el inconveniente de este método. Estoy limitado a seleccionar solo una columna de texto que sean todas iguales en posición vertical .

hobbes3
fuente
99
Mejor manera: ":% s / ^ / vendor_ /"
Paul Tomblin
1
Gracias por la respuesta. Eso funciona si solo quiero agregar una palabra a cada línea. Pero el método que uso se puede hacer en cualquier posición. Permítanme agregar otro mi ejemplo con un ejemplo más complicado.
hobbes3
3
Luego resalte las líneas que desea cambiar con shift-V, y escriba un comando apropiado de búsqueda y reemplazo - en el segundo ejemplo,:s/models\./\0whatever./
Paul Tomblin
Muchas formas de lograr lo anterior. Para responder completamente a todas las partes de la pregunta, entonces la parte 1) ya sea regex o modo visual, edito esc funciona bien como se ofrece en las respuestas (prefiero la selección visual en GVIM). Para la parte 2), macro es quizás más fácil como lo ofrece Brian Neal. El mejor recurso que conozco para todos estos tipos de "cómo hacer" es Practical Vim de Drew Neil. Excelente lectura rápida y referencia de peso ligero cada vez que olvida una fórmula. Espero que esta recomendación ayude a alguien, valdrá la pena el esfuerzo para muchos usuarios de vim.
arcseldon el
@Paul: Y si estás contando pulsaciones de teclas , puedes reemplazarlas \0por &.
icktoofay

Respuestas:

912
  1. Mueva el cursor hacia nadentro name.
  2. Ingrese al modo de bloqueo visual ( Ctrlv).
  3. Presione jtres veces (o 3j).
  4. Presione I(mayúscula i).
  5. Teclear vendor_. Nota: Solo actualizará la pantalla en la primera línea, hasta que Escse presione (6.), momento en el cual se actualizarán todas las líneas.
  6. Presione Esc.

mini-screencast demostrando el método

Se Idebe usar una mayúscula en lugar de una minúscula i, porque la minúscula ise interpreta como el comienzo de un objeto de texto , que es bastante útil por sí solo, por ejemplo, para seleccionar dentro de un bloque de etiquetas ( it):

mini-screencast que muestra la utilidad del objeto de texto 'it'

icktoofay
fuente
12
No pude hacer que esto funcione en Windows (ya que CTRL + V está asignado para pegar en el portapapeles). Pero Vim también ha asignado esto a Ctrl + Q para la versión de Windows.
Arnestig
2
@Ven: Vim no está realmente ocupado durante ese tiempo, solo está esperando que presiones otra tecla y, finalmente, se agota el tiempo de espera. Dos experimentos para usted: primero, intente presionar escape y luego presione inmediatamente otra tecla, como jo ^L. Deberías ver que Vim no estaba ocupado después de todo; solo estaba esperando. En segundo lugar, intente cambiar 'timeout'a un valor inferior, como 80(en lugar del predeterminado 1000) y observe que se agota el tiempo de espera más rápidamente.
icktoofay
1
@icktoofay Parece que la variable que quiere establecer timeoutlenno lo es timeout.
jez
44
@ANjaNA: si donde desea insertar está todo en la misma columna (por ejemplo, si los números tienen la misma longitud), puede usar la misma técnica, excepto presionando en Alugar de I, que se insertará después del bloque seleccionado en lugar de antes. Sin embargo, si sus líneas tienen longitudes diferentes, eso no funcionará; Me gusta usar una sustitución que coincida con el final de cada línea para eso, por ejemplo, seleccionar algunas líneas y usarlas :s/$/inserted/.
icktoofay
3
Tuve que presionar la flecha hacia abajo después de presionar esc para que esto funcione
GeoSword
69

Otro enfoque es usar el comando .( dot) en combinación con I.

  1. Mueve el cursor donde quieras comenzar
  2. prensa I
  3. Escriba el prefijo que desee (por ejemplo vendor_)
  4. Presione esc.
  5. Presione jpara bajar una línea
  6. Escriba .para repetir la última edición, insertando automáticamente el prefijo nuevamente
  7. Alterne rápidamente entre jy.

Encuentro que esta técnica es a menudo más rápido que el modo de bloque visual para un pequeño número de adiciones y tiene la ventaja añadida de que si no es necesario insertar el texto en cada línea en un rango que puede saltar fácilmente pulsando adicionales j's .

Tenga en cuenta que para un gran número de adiciones contiguas, el enfoque de bloque o macro probablemente será superior.

Danprice
fuente
Es bueno ver otro enfoque.
Ibn Saeed
Prefiero esto por solo unas pocas líneas. Mucho más fácil de ejecutar IMO.
Dan Bechard
Después de escribir el prefijo que desea, ¿no necesita presionar la tecla de escape?
iamnotsam
41
  1. Seleccione las líneas que desea modificar usando CtrlV.
  2. Prensa:

    • I: Insertar antes de lo que está seleccionado.
    • A: Agregar después de lo seleccionado.
    • c: Reemplazar lo seleccionado.
  3. Escribe el nuevo texto.

  4. Presione Escpara aplicar los cambios a todas las líneas seleccionadas.
Loukan ElKadi
fuente
44
¡Excelente! Solo destacaría el paso final Escpara los novatos de VIM como yo: ¡me tomó un tiempo darme cuenta de que los cambios se propagan "más tarde"!
Bugs Bunny
1
Agradable, no sabía sobre las opciones "A" y "C" también.
hobbes3
¿Por qué no funciona esto v? Puedo hacerlo Ctrl+V --> A, pero val seleccionar el texto no funciona, Asolo se agrega a esa línea. ¿No son ambos selección? Además, muy extraño: Asolo se agrega al final de la línea SI extiendo el bloque visual hasta el final de la línea; de lo contrario, se agrega donde termina el bloque visual para cada línea. Es como si no reconociera una diferencia entre ay A.
Alex G
1
Necesitaba usar en clugar de C, pero funcionó perfectamente bien. Gracias
Tarol
29

Usaría una macro para registrar mis acciones y luego la repetiría.

  1. Coloque el cursor sobre la primera letra del nombre .
  2. Presione qqpara comenzar a grabar en el búfer q.
  3. Presione ipara ingresar al modo de inserción, escriba vector_ y luego presioneEsc para salir del modo de inserción.
  4. Ahora presiona 0para volver al comienzo de la línea.
  5. Ahora presiona jpara bajar.
  6. Ahora presione qnuevamente para detener la grabación.

Ahora tienes una buena macro.

Escriba 3@qpara ejecutar su macro tres veces para hacer el resto de las líneas.

Brian Neal
fuente
¿Es "q" especial (para "macro rápida")?
Peter Mortensen
¿Cómo se puede hacer persistente la macro (trabajando en varias sesiones)?
Peter Mortensen
@PeterMortensen Vim tiene una característica llamada sesiones que persistirán en los buffers (y muchas otras cosas) que puede analizar.
Brian Neal
27
:%s/^/vendor_/

¿O me estoy perdiendo algo?

srini.venigalla
fuente
Te estás perdiendo el hecho de que es probable que sea un subtexto en un archivo con muchas otras líneas en las que el vender_prefijo no es deseado.
Dan Bechard
99
@dan Si solo se necesita un subtexto, puede limitar la búsqueda a un conjunto de números de línea, por ejemplo1,4s/^/vendor_/
Brad Koch,
1
@BradKoch Interesante. No estaba al tanto de las restricciones del número de línea, gracias por eso.
Dan Bechard
8
es interesante, pero lo más práctico es bloquear visualmente select con Vy escribir :. Prefijará la expresión ed con la :'<,'>que se aplicará la ed solo a la selección con:'<,'>s/^/vendor_/
Dolanor
12

Actualizado en enero de 2016

Si bien la respuesta aceptada es una gran solución, en realidad es un poco menos pulsaciones de teclas y se escala mejor, en principio en función de la respuesta aceptada.

  1. Mueva el cursor hacia nadentro name.
  2. Ingrese al modo de bloqueo visual ( ctrlv).
  3. prensa 3j
  4. Presione I.
  5. Teclear vendor_.
  6. Presione esc.

ilustración visual

Tenga en cuenta que esto tiene menos pulsaciones de teclas que la respuesta aceptada proporcionada (compare el Paso 3). Solo contamos la cantidad de j acciones a realizar.

Si tiene habilitados los números de línea (como se ilustra arriba) y conoce el número de línea al que desea moverse, entonces el paso 3 se puede cambiar a # Gdonde # es el número de línea deseado.

En nuestro ejemplo anterior, esto sería 4G. Sin embargo, cuando se trata de unos pocos números de línea, un recuento explícito funciona bien.

arcseldon
fuente
7

Quería comentar muchas líneas en algún archivo de configuración en un servidor que solo tenía vi (no nano), por lo que el método visual también era engorroso. Así es como lo hice.

  1. Abrir documento vi file
  2. Mostrar números de línea :set number!o:set number
  3. Luego use los números de línea para reemplazar el inicio de línea con "#", ¿cómo?

:35,77s/^/#/

Nota: los números son inclusivos, las líneas de la 35 a la 77, ambas incluidas serán modificadas.

Para descomentar / deshacer eso, simplemente use :35,77s/^#//

Si desea agregar una palabra de texto como comentario después de cada línea de código, también puede usar:

:35,77s/$/#test/ (para lenguajes como Python)

:35,77s/;$/;\/\/test/ (para lenguajes como Java)

créditos / referencias:

  1. /unix/84929/uncommenting-multiple-lines-of-code-specified-by-line-numbers-using-vi-or-vim

  2. /unix/120615/how-to-comment-multiple-lines-at-once

computacion
fuente
Esta fue la solución perfecta para mí, ya que a menudo solo uso vim-tiny.
JSON C11
7

También puede tener un caso de uso en el que desea eliminar un bloque de texto y reemplazarlo.

Me gusta esto

Hello World

Hello World

A

Hello Cool

Hello Cool

Puede simplemente bloquear visualmente seleccionar "Mundo" en ambas líneas.

Escriba cpara el cambio: ahora estará en modo de inserción.

Inserta las cosas que quieras y presiona escapar.

Ambos se reflejan verticalmente. Funciona igual que 'I', excepto que reemplaza el bloque con el nuevo texto en lugar de insertarlo.

Nishant
fuente
6

Supongamos que tiene este archivo:

something

name
comment
phone
email

something else
and more ...

Desea agregar "proveedor_" delante de "nombre", "comentario", "teléfono" y "correo electrónico", independientemente de dónde aparezcan en el archivo .

:%s/\<\(name\|comment\|phone\|email\)\>/vendor_\1/gc

La cbandera le pedirá confirmación. Puede soltar eso si no desea la solicitud.

Manish
fuente
5

Una alternativa que puede ser más flexible:

Ejemplo: para ingresar el texto XYZ al comienzo de la línea

:%norm IXYZ

¿Que esta pasando aqui?

  • % == Ejecutar en cada línea
  • norm == Ejecute las siguientes teclas en modo normal
  • I == Insertar al comienzo de la línea
  • XYZ == El texto que desea ingresar

Luego golpeas Enter, y se ejecuta.

Específico a su solicitud:

:%norm Ivendor_

También puede elegir un rango particular:

:2,4norm Ivendor_

O ejecutar sobre un rango visual seleccionado:

:'<,'>norm Ivendor_
Aubrey Lavigne
fuente
1
¿es posible enviar secuencias de teclas como <Esc> mientras está en modo de inserción (norma Iabc <ESC>) para hacer cosas más interesantes?
Batbrat
1
@batbrat ¡Acabo de resolver esto! Puede presionar ctrl-v ctrl-[para insertar un "Esc escapado", que lo devuelve al "modo normal" con el propósito de su comando normal. Acabo de probar esto con '<,'>norm Iaa^[ysiw", ¿dónde ^[está el Esc escapado?
Aubrey Lavigne
4
Use Ctrl+V to enter visual block mode
Move Up/Down to select the columns of text in the lines you want to comment.
Then hit Shift+i and type the text you want to insert.
Then hit Esc, wait 1 second and the inserted text will appear on every line
Arpan Saini
fuente
¿Este método funciona para todas las versiones de vim o requiere complementos de vim? la razón por la que pregunto es b / c, a veces funciona en algunas máquinas, pero a veces no. No puedo entender la diferencia. vim que viene con git en windows: no puedo hacerlo funcionar. en algunas máquinas Linux ubuntu y centos, no puedo hacer que funcione. He tenido éxito en algunos casos raros, pero no pude reproducir el éxito. Es un misterio. nada parece suceder después de que golpeé ESC.
davidj411
Curiosamente, funciona para mí ahora. nada ha cambiado, excepto tal vez las estrellas :) mientras buscaba una solución a mi problema, encontré algo en esta página, aunque menciona algo que buscar en vim vim.wikia.com/wiki/Inserting_text_in_multiple_lines En Vim, verifique que haya la función de operadores de bloque (I, A y más) ingresando el comando: versión. La salida debe incluir + visualextra.
davidj411
Quise agregar un comentario en general, no a tu respuesta. La mayoría de estas respuestas dicen lo mismo pero usan palabras diferentes. La mía tenía algo diferente que ofrecer e incluía un enlace.
davidj411
2
  1. Ctrl + v para ir al modo de bloqueo visual
  2. Seleccione las líneas con las flechas hacia arriba y hacia abajo.
  3. Ingrese minúsculas 3i(presione tres veces minúsculas I )
  4. I(presione mayúscula I. Eso lo llevará al modo de inserción).
  5. Escribe el texto que deseas agregar
  6. Esc
  7. Presione la flecha hacia abajo
Arpan Saini
fuente