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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.