I'm not a tech person. I've been using Neovim for the last year or so for writing, and I love it. But I'm considering making the switch to Emacs for the ability to use non-mono fonts. I use markdown because I collaborate with others.
In Neovim, I frequently use a vimscript function that I cannot figure out how to replicate in Emacs. It allows me to sort lines while maintaining grouping, both with headers and lists.
For example, it'd sort
- B
- 2
- A
- 1
to
- A
- 1
- B
- 2
Does anyone know how to replicate this in emacs? Here is the vimscript function.
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>)