2
\$\begingroup\$

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:\ 
\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.