I read a little bit more, and there's a function in vimscript called sort()
which can receive a function to compare both items. Here's the help page:
sort({list} [, {func} [, {dict}]]) sort() E702
Sort the items in {list} in-place. Returns {list}. If you
want a list to remain unmodified make a copy first:
:let sortedlist = sort(copy(mylist))
Uses the string representation of each item to sort on.
Numbers sort after Strings, Lists after Numbers.
For sorting text in the current buffer use :sort.
When {func} is given and it is one then case is ignored.
{dict} is for functions with the "dict" attribute. It will be
used to set the local variable "self". Dictionary-function
When {func} is a Funcref or a function name, this function
is called to compare items. The function is invoked with two
items as argument and must return zero if they are equal, 1 or
bigger if the first one sorts after the second one, -1 or
smaller if the first one sorts before the second one.
Example:
func MyCompare(i1, i2)
return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
endfunc
let sortedlist = sort(mylist, "MyCompare")
A shorter compare version for this specific simple case, which
ignores overflow:
func MyCompare(i1, i2)
return a:i1 - a:i2
endfunc
So, something like
" Compare function
fu! MyCompare(i1, i2)
let l:score1 = i1 =~ '.\{-}(foo)' ? 2 : i1 =~ '.\{-}(bar)' ? 1 : 0
let l:score2 = i2 =~ '.\{-}(foo)' ? 2 : i2 =~ '.\{-}(bar)' ? 1 : 0
return l:score1 == l:score2 ? 0 : l:score1 > l:score2 ? 1 : -1
endfu
"Function to sort the lines
fu! SortLines(linestart, lineend)
let l:lines = getline(a:linestart, a:lineend)
sort(l:lines,"MyCompare")
" Put the sorted lines in the file
let l:nlines = a:lineend - a:linestart
exe 'normal! '.a:linestart.'G'.l:nlines.'dd'
let @l = join(l:lines, "\n")
exe 'normal! '.a:linestart.'G"lP'
endfu
" Calling the function
:call SortLines(1,2)