¿Hay una manera dedicada de fusionar dos bloques de texto entrelazando líneas, como pasar de esto:
a1
a2
a3
a4
b1
b2
b3
b4
a ese:
a1
b1
a2
b2
a3
b3
a4
b4
en unos pocos comandos?
EDITAR : Realmente me gusta la solución de Sato Katsura , así es como la he implementado:
function! Interleave()
" retrieve last selected area position and size
let start = line(".")
execute "normal! gvo\<esc>"
let end = line(".")
let [start, end] = sort([start, end], "n")
let size = (end - start + 1) / 2
" and interleave!
for i in range(size - 1)
execute (start + size + i). 'm' .(start + 2 * i)
endfor
endfunction
" Select your two contiguous, same-sized blocks, and use it to Interleave ;)
vnoremap <pickYourMap> <esc>:call Interleave()<CR>
vimscript
formatting
merge
iago-lito
fuente
fuente
scroll-binding
dos ventanas de Vim.b1
, luego presionévip
para seleccionar todo el fragmento, luego,it
cuál es el<map-I've-Picked>
. ¿No está funcionando de tu lado?Respuestas:
No hay una forma dedicada de hacerlo (hasta donde yo sé), pero sí, se puede hacer con algunos comandos:
Puedes ejecutarlo con
:call Interleave(5, 8, 1)
. El primer parámetro es la primera línea para mover, el segundo la última línea y el tercero donde moverlos. Probablemente desee activar los números de línea para ver lo que está haciendo (:set number
).Esto supone que los bloques no se superponen. Ver
:help :move
y:help range()
comprender cómo funciona la función.Probablemente hay mejores formas de recoger los dos bloques. Hay un complemento flotando que se supone que te permite intercambiar dos bloques. No recuerdo el nombre del complemento, pero el autor (¿quizás el famoso Dr. Chip?) Ha pensado más en encontrar una interfaz que yo. :)
fuente
start
ysize
. Con una función homebrew que recupera esos valores de una selección, será perfecto. Estoy trabajando en ello. :)Aquí hay otra alternativa:
Primero copie las líneas que están debajo de las 4 líneas después de la línea actual (
:h :t
) luego elimine las líneas b consecutivas (:h :d
)Aún mejor es este comando:
Lo que significa que, para cada línea que comienza con a, encuentre la siguiente línea que comienza con 'b' y muévala a debajo de la línea actual.
fuente
.+,$d
lugar, y eso funcionó (como lo hizo.+,.+4d
)./^\s*b
a otro:range
. por ejemplo: seleccione el primer bloque, ejecute'<,'>g/^/'>+1m.
'>+1
marca el comienzo del segundo bloque.Si quieres divertirte un poco con macros y marcas, puedes probar algo como esto:
Primero ponga una marca (aquí
a
) en la línea que contienea1
conma
Vaya a la línea que contiene
b1
y márquela conmb
Comience a grabar una macro en el registro que desee (aquí el registro
q
) conqq
Inserte lo siguiente en su macro:
ddmb'apjma'b
Deja de grabar la macro con
q
Reproducirlo tantas veces como sea necesario con
X@q
dondeX
es el número de veces para reproducirlo.Para detallar la macro:
Editar Como lo mencionó lago-lito en los comentarios, este método sobrescribirá las marcas y los tampones.
Para las marcas, no creo que sea un problema real: rara vez uso las 26 marcas en un búfer y creo que la mayoría de las veces encontraré 2 marcas libres.
Para el búfer, es posible guardarlo en una variable temporal: antes de grabar la macro, use
:let saveReg=getreg('"')
para guardar el registro y, una vez que se realiza la acción, use:call setreg('"', saveReg)
para regresar el registro a su estado anterior.De todos modos, debo admitir que esta solución es solo una solución rápida y no es óptima: en mi opinión, la respuesta de Christan es la mejor y debe aceptarse porque no interfiere con los buffers y las marcas, no obliga al usuario a crear una función y muestra el poder del comando global.
fuente
getreg()
ysetreg()
para guardar la memoria intermedia. Pero estoy de acuerdo en que no es una solución óptima :-)Acabo de ver otra pregunta similar y la solución consiste en:
Salta al medio más uno:
Y correr:
fuente