How do I sort multiple blocks of text by the first line in each block in Vim?
I have multiple blocks of text, or in other words, multiple functions like this:
def ==(other)
...
end
def to_s(full=false)
...
end
def to_a
...
end
def to_hash
...
end
def inspect
...
end
I want to sort the functions alphabetically by the function signature. How can this most easily be done in Vim?
It's relatively simple (and, I believe, close to what Jason had in mind) :
-
turn all your functions into one liners by replacing all newlines with some fancy character:
:g/def/,/end/s/\n/§
-
sort those one liners with:
:%sort
-
expand all your functions back to their initial individual state:
:g/def/s/§/\r
I've written the AdvancedSorters plugin to simplify the three separate steps given in @romainl's answer into a single command:
:SortRangesByRange /^def\>/,/^end\>\_s*\zs$/
The pattern here is slightly more complex to also properly include the separating empty lines.
The best way I can think of doing this without writing a function that parses the definitions, would be to substitute the line delimiters not preceded by end
for another unique delimiter (+EOL+?), and then :sort
, and re-substitute the line delimiters. It could probably be recorded to a macro.
A function might be better though, in the case that you want to use visual selection.