My first delve into vimscript was writing a plugin for folding markdown lists.
I reckon there are a few idioms I'm missing here, so I would greatly appreciate any comments to improve the plugin.
I've noticed something akin to "header guards" in C family languages among popular plugins:
if exists('g:touchdown__loaded')
finish
endif
" ... plugin body goes here ..."
let g:touchdown__loaded=1
Logic for folding markdown lists is handled in the next chunk:
function! IndentLevel(lnum)
return indent(a:lnum) / &shiftwidth
endfunction
function! NextNonBlankLine(lnum)
let numlines = line('$')
let current = a:lnum + 1
while current <= numlines
if getline(current) =~? '\v\S'
return current
endif
let current += 1
endwhile
return -2
endfunction
function! GetListFold(lnum)
if getline(a:lnum) =~? '\v^\s*$'
return '-1'
endif
let this_indent = IndentLevel(a:lnum)
let next_indent = IndentLevel(NextNonBlankLine(a:lnum))
if next_indent == this_indent
return this_indent
elseif next_indent < this_indent
return this_indent
elseif next_indent > this_indent
return '>' . next_indent
endif
endfunction
I've also set up a custom text for the lists, but I want to make sure my logic doesn't apply to folds that aren't markdown lists. Calling foldtext when the regex doesn't match is the closest thing I know to do:
function! GetFoldText()
if (match(getline(v:foldstart), "[\s\t]*[-\*][\s\t]*.*") != -1)
let nl = v:foldend - v:foldstart
let linetext = substitute(getline(v:foldstart),"-","+",1)
let txt = linetext . "\t (" . nl . ' lines hidden)'
else
let txt = foldtext()
endif
return txt
endfunction
Finally I apply the fold strategy here. One thing to note is I want this to only apply to markdown files, but I'm not sure how to accomplish that idiomatically:
setlocal foldtext=GetFoldText()
setlocal foldmethod=expr
setlocal foldexpr=GetListFold(v:lnum)
setlocal fillchars=fold:\