-
-
Save TechIsCool/0be56d68fbf9eb767e595b4c4df0508b to your computer and use it in GitHub Desktop.
Sort groups of lines in vim
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" :[range]SortGroup[!] [n|f|o|b|x] /{pattern}/ | |
" e.g. :SortGroup /^header/ | |
" e.g. :SortGroup n /^header/ | |
" See :h :sort for details | |
function! s:sort_by_header(bang, pat) range | |
let pat = a:pat | |
let opts = "" | |
if pat =~ '^\s*[nfxbo]\s' | |
let opts = matchstr(pat, '^\s*\zs[nfxbo]') | |
let pat = matchstr(pat, '^\s*[nfxbo]\s*\zs.*') | |
endif | |
let pat = substitute(pat, '^\s*', '', '') | |
let pat = substitute(pat, '\s*$', '', '') | |
let sep = '/' | |
if len(pat) > 0 && pat[0] == matchstr(pat, '.$') && pat[0] =~ '\W' | |
let [sep, pat] = [pat[0], pat[1:-2]] | |
endif | |
if pat == '' | |
let pat = @/ | |
endif | |
let ranges = [] | |
execute a:firstline . ',' . a:lastline . 'g' . sep . pat . sep . 'call add(ranges, line("."))' | |
let converters = { | |
\ 'n': {s-> str2nr(matchstr(s, '-\?\d\+.*'))}, | |
\ 'x': {s-> str2nr(matchstr(s, '-\?\%(0[xX]\)\?\x\+.*'), 16)}, | |
\ 'o': {s-> str2nr(matchstr(s, '-\?\%(0\)\?\x\+.*'), 8)}, | |
\ 'b': {s-> str2nr(matchstr(s, '-\?\%(0[bB]\)\?\x\+.*'), 2)}, | |
\ 'f': {s-> str2float(matchstr(s, '-\?\d\+.*'))}, | |
\ } | |
let arr = [] | |
for i in range(len(ranges)) | |
let end = max([get(ranges, i+1, a:lastline+1) - 1, ranges[i]]) | |
let line = getline(ranges[i]) | |
let d = {} | |
let d.key = call(get(converters, opts, {s->s}), [strpart(line, match(line, pat))]) | |
let d.group = getline(ranges[i], end) | |
call add(arr, d) | |
endfor | |
call sort(arr, {a,b -> a.key == b.key ? 0 : (a.key < b.key ? -1 : 1)}) | |
if a:bang | |
call reverse(arr) | |
endif | |
let lines = [] | |
call map(arr, 'extend(lines, v:val.group)') | |
let start = max([a:firstline, get(ranges, 0, 0)]) | |
call setline(start, lines) | |
call setpos("'[", start) | |
call setpos("']", start+len(lines)-1) | |
endfunction | |
command! -range=% -bang -nargs=+ SortGroup <line1>,<line2>call <SID>sort_by_header(<bang>0, <q-args>) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment