How to efficiently interlace multiple groups of lines in Vim?

Somewhere in the depths of my ~/.vim files I have an :Interleave command (appended below). With out any arguments :Interleave will just interleave just as normal. With 2 arguments how ever it will specify how many are to be grouped together. e.g. :Interleave 2 1 will take 2 rows from the top and then interleave with 1 row from the bottom.

Now to solve your problem

:1,/c/-1Interleave
:Interleave 2 1
  • 1,/c/-1 range starting with the first row and ending 1 row above the first line matching a letter c.
  • :1,/c/-1Interleave basically interleave the groups of a's and b's
  • :Interleave 2 1 the range is the entire file this time.
  • :Interleave 2 1 interleave the group of mixed a's and b's with the group of cs. With a mixing ratio of 2 to 1.

The :Interleave code is below.

command! -bar -nargs=* -range=% Interleave :<line1>,<line2>call Interleave(<f-args>)
fun! Interleave(...) range
  if a:0 == 0
    let x = 1
    let y = 1
  elseif a:0 == 1
    let x = a:1
    let y = a:1
  elseif a:0 == 2
    let x = a:1
    let y = a:2
  elseif a:0 > 2
    echohl WarningMsg
    echo "Argument Error: can have at most 2 arguments"
    echohl None
    return
  endif
  let i = a:firstline + x - 1
  let total = a:lastline - a:firstline + 1
  let j = total / (x + y) * x + a:firstline
  while j < a:lastline
    let range = y > 1 ? j . ',' . (j+y) : j
    silent exe range . 'move ' . i
    let i += y + x
    let j += y
  endwhile
endfun

Tags:

Vim