Shuffle lines in Vim

In a pinch, I needed to randomize the order of a few thousand lines of plain text. In Linux you can just pipe the file through sort, even right inside Vim:

:%!sort -R

But I was stuck on Windows. And I don't know how to randomize a file in native Vim script. But doing it in Ruby is pretty easy, and luckily, Vim has awesome Ruby support. Tne minutes' work and a few peeks at :h ruby and we have a successful, working kludge:

function! ShuffleLines()
ruby << EOF
    buf = VIM::Buffer.current
    firstnum =  VIM::evaluate('a:firstline')
    lastnum = VIM::evaluate('a:lastline')
    lines = []
    firstnum.upto(lastnum) do |lnum|
      lines << buf[lnum]
    end
    lines.shuffle!
    firstnum.upto(lastnum) do |lnum|
      buf[lnum] = lines[lnum-firstnum]
    end
EOF
endfunction

2011-07-07 23:32 - Edited to remove a superfluous line.

2011-07-09 21:33 - Wrong parameter for sort, oops.

July 07, 2011 @ 7:07 AM PDT
Cateogory: Programming
Tags: Ruby, Vim

5 Comments

Thom
Quoth Thom on July 07, 2011 @ 9:38 AM PDT

What is this 'vim' of which you speak?

jerojasro
Quoth jerojasro on July 07, 2011 @ 11:34 AM PDT

I saw something similar in IRC, not as fancy, but depending only on vimscript; I documented it here:

http://devnull.li/~jerojasro/blog/posts/randomize_lines_in_a_file/

SwifT
Quoth SwifT on July 09, 2011 @ 1:49 AM PDT

Small typo: sort -R randomizes, sort -r just reverses the sort order.

Brian
Quoth Brian on July 09, 2011 @ 2:32 PM PDT

Thanks SwifT.

cvjcvj
Quoth cvjcvj on May 01, 2012 @ 7:12 AM PDT

I think that you can replace 8 lines of your code with that onliner:

buf[ firstnum..lastnum ] = buf[ firstnum..lastnum ].shuffle

Speak your Mind

You can use Markdown in your comment.
Email/URL are optional. Email is only used for Gravatar.

Preview