¿Cómo insertar texto repetitivo con una diferencia menor en vim?

11

Quiero insertar texto como este:

similar text wordA similar text ...
similar text wordB similar text ...
similar text wordC similar text ...

Sé que puedo pegar el texto muchas veces y luego usar la sustitución para cambiar una sola palabra para cada línea, sin embargo, todavía encuentro este método muy inconveniente.

¿Hay alguna manera de guardar una palabra o una lista de palabras en una "variable" y luego usar esta variable para generar texto similar?


EDITAR Hice algo poco claro en la pregunta original, de hecho, estoy tratando de hacer algunas definiciones de funciones muy similares, por lo que wordA wordB... puede aparecer muchas veces en cada clon de texto y el texto puede contener muchas líneas. El patrón es exactamente así:

similar_text1 wordA similar_text2 wordA similar_text3 ...
similar_text1 wordB similar_text2 wordB similar_text3 ...
similar_text1 wordC similar_text2 wordC similar_text3 ...

(el texto puede contener nuevas líneas, y la palabra A, la palabra B ... pueden existir muchas veces)


2nd EDIT Las partes "similar_text" pueden ser diferentes cada vez que hago ese trabajo, por lo que la solución para este trabajo es mejor ser reutilizable. Porque estoy tratando de hacer definiciones de funciones muy parecidas, o una tabla de mapeo de cadena a función.

Después de leer las respuestas y un poco de práctica, considero que es más conveniente considerar este trabajo como una especie de sustitución, porque "parte1", "parte2" ... "parteN" separadas que pueden contener líneas nuevas es difícil de escribir, así que escriba primero una plantilla:

similar_text1 $WORD similar_text2 $WORD similar_text3 ...
(text may contain <ENTER>, make sure $WORD not exist in "similar_text" parts )

Luego, tratar de poner clones del texto pero reemplazar $ WORD con una lista de palabras es un pensamiento más directo.

Entonces, parece que mi problema cambió para ser "¿Cómo clonar un bloque de texto muchas veces, pero cada vez sustituyendo una palabra clave con una palabra de una lista?"

social_loser
fuente
Por eso se utilizan registros. Puede tirar (copiar) texto a un registro y luego usar ese registro. Las macros se pueden usar para hacer tareas similares y repetitivas.
SibiCoder

Respuestas:

7

Puede usar la siguiente función:

function! GenerateLines()
    let firstpart="similar text part 1"
    let secondpart="similar text part 2"

    let words=["wordA","wordB","wordC","wordD","wordE"]

    for word in words
        let line = firstpart . word . secondpart
        call append(line('.')+1, line)
        normal j
    endfor
endfunction

En las variables firstparty secondpartponer el texto para repetir antes y después de las palabras y en la lista wordsponer las palabras que deben cambiar.

Luego, el bucle creará el contenido de la línea para cada palabra de la lista, inserte la línea en el búfer y vaya a esta nueva línea.

A continuación, puede simplemente llamar a la función: call GenerateLines().


Editar Para facilitar la manipulación, también puede pasar las diferentes partes como argumentos, la función debería verse así:

function! GenerateLines(firstpart, secondpart, words)
    for word in a:words
        call append(line('.')+1, a:firstpart . word . a:secondpart)
        normal j
    endfor
endfunction

Y puedes llamarlo así:

call GenerateLines("first part", "second part", ["wordA","wordB","wordC","wordD","wordE"])
statox
fuente
Podrías evitar el bucle con call map(a:words, 'a:firstpart . v:val . a:secondpart')y call append(line('.'), a:words).
Antony
Como a menudo hago este tipo de edición con "firstpart" y "secondpart" muy largas, incluso "thirdpart", y estas partes pueden contener nuevas líneas, parece ser demasiado largo para escribir tanto en modo comando, por lo que tal vez sea más conveniente para arrastrar el texto a los registros y luego usar las funciones para generar texto a partir de los registros?
social_loser
Edité la pregunta, cambia mucho, disculpe las molestias.
social_loser
5

Mi estrategia en tales casos variará, pero a menudo sigue los siguientes pasos:

  1. Escriba las palabras únicas, p. Ej.

    wordA
    wordB
    ...
    wordK
    
  2. Ya sea

    a) hacer una búsqueda y reemplazar, por ejemplo

    :%s/\w\+/similar text \0 similar text .../
    

    b) o use el modo de bloqueo visual, vea :h blockwise-visual. En particular, seleccionaré las palabras y las usaré Ipara insertar texto similar al frente, o Apara agregar texto similar después.

Yo diría que esta estrategia tiene sentido cuando haces este tipo de tarea de edición relativamente raramente. Sin embargo, si encuentra que necesita hacer esto con frecuencia, entonces debe seguir la sugerencia de @ statox con una función que expande la lista de palabras.

Karl Yngve Lervåg
fuente
Creo que la solución depende de dónde viene la lista de palabras. Si es de un archivo, entonces :readseguido por su sustitución tiene mucho sentido.
Antony
Su solución es fácil de hacer y resuelve fácilmente el problema que hice en la pregunta original. Sin embargo, hay algunos errores en mi publicación original, hice 2 ediciones y cambia mucho, gracias por la respuesta, perdón por mi cambio y mal inglés :)
social_loser
@social_loser puede adaptar esta solución utilizando "\ r" para representar una nueva línea en la parte de reemplazo de la sustitución
frangio
2

Argumentaré que este es un trabajo para el bloque visual ( Ctrl+ v). Primero escribiría todas las palabras distintas:

wordA
wordB
wordC
wordD
wordE

Comenzando con el cursor en el primero w, realizaría:

<c-v>5j$yA <esc>pA <esc>p

Puedo controlar cuántas columnas necesito presionando A <esc>pcuantas veces quiera. Supongamos que necesitaba tres columnas, tal como se muestra en el comando anterior. Ahora tenemos esto:

wordA wordA wordA
wordB wordB wordB
wordC wordC wordC
wordD wordD wordD
wordE wordE wordE

Y el cursor está al principio del 3er wordAen la primera línea. A continuación, bloquearía seleccionar la columna de espacio en blanco entre las columnas que van hacia atrás y agregan el texto en el medio. Desde la ubicación actual del cursor:

h<c-v>5jI similar text 3<esc>

Esto da como resultado (el% marca la posición del cursor):

wordA wordA%similar text 3 wordA
wordB wordB similar text 3 wordB
wordC wordC similar text 3 wordC
wordD wordD similar text 3 wordD
wordE wordE similar text 3 wordE

Repita para la siguiente columna:

bh<c-v>5jI similar text 2<esc>

Y la última / primera columna (la del lado izquierdo):

b<c-v>5jIsimilar text 1 <esc>

Finalmente resultando en:

similar text 1 wordA similar text 2 wordA similar text 3 wordA
similar text 1 wordB similar text 2 wordB similar text 3 wordB
similar text 1 wordC similar text 2 wordC similar text 3 wordC
similar text 1 wordD similar text 2 wordD similar text 3 wordD
similar text 1 wordE similar text 2 wordE similar text 3 wordE

Actualización: agregado un screencast

ingrese la descripción de la imagen aquí


Esto parece ser una gran cantidad de tipeo, pero en realidad es muy fácil acostumbrarse. Le brinda la libertad de cambiar la cantidad de palabras, la cantidad de columnas e incluso el espacio entre las columnas.

El inconveniente es que necesita saber la cantidad de palabras distintas que está usando. Tengo un 5código fijo en todos los comandos anteriores porque es el número de filas en las que operan los comandos.

Nota de depuración: todos los comandos comienzan y terminan en modo normal, si te encuentras en modo visual o de inserción al final de un comando estás haciendo algo mal.

grochmal
fuente