SHARE
TWEET

Untitled

a guest Oct 21st, 2018 144 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. " Fold expressions {{{1
  2. function! StackedMarkdownFolds()
  3.   if HeadingDepth(v:lnum) > 0
  4.     return ">1"
  5.   else
  6.     return "="
  7.   endif
  8. endfunction
  9.  
  10. function! NestedMarkdownFolds()
  11.   let depth = HeadingDepth(v:lnum)
  12.   if depth > 0
  13.     return ">".depth
  14.   else
  15.     return "="
  16.   endif
  17. endfunction
  18.  
  19. " Helpers {{{1
  20. function! s:SID()
  21.   return matchstr(expand('<sfile>'), '<SNR>\d\+_')
  22. endfunction
  23.  
  24. function! HeadingDepth(lnum)
  25.   let level=0
  26.   let thisline = getline(a:lnum)
  27.   let hashCount = len(matchstr(thisline, '^#\{1,6}'))
  28.   if hashCount > 0
  29.     let level = hashCount
  30.   else
  31.     if thisline != ''
  32.       let nextline = getline(a:lnum + 1)
  33.       if nextline =~ '^=\+\s*$'
  34.         let level = 1
  35.       elseif nextline =~ '^-\+\s*$'
  36.         let level = 2
  37.       endif
  38.     endif
  39.   endif
  40.   if level > 0 && LineIsFenced(a:lnum)
  41.     " Ignore # or === if they appear within fenced code blocks
  42.     let level = 0
  43.   endif
  44.   return level
  45. endfunction
  46.  
  47. function! LineIsFenced(lnum)
  48.   if exists("b:current_syntax") && b:current_syntax ==# 'markdown'
  49.     " It's cheap to check if the current line has 'markdownCode' syntax group
  50.     return s:HasSyntaxGroup(a:lnum, 'markdownCode')
  51.   else
  52.     " Using searchpairpos() is expensive, so only do it if syntax highlighting
  53.     " is not enabled
  54.     return s:HasSurroundingFencemarks(a:lnum)
  55.   endif
  56. endfunction
  57.  
  58. function! s:HasSyntaxGroup(lnum, targetGroup)
  59.   let syntaxGroup = map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")')
  60.   for value in syntaxGroup
  61.     if value =~ '\vmarkdown(Code|Highlight)'
  62.       return 1
  63.     endif
  64.   endfor
  65. endfunction
  66.  
  67. function! s:HasSurroundingFencemarks(lnum)
  68.   let cursorPosition = [line("."), col(".")]
  69.   call cursor(a:lnum, 1)
  70.   let startFence = '\%^```\|^\n\zs```'
  71.   let endFence = '```\n^$'
  72.   let fenceEndPosition = searchpairpos(startFence,'',endFence,'W')
  73.   call cursor(cursorPosition)
  74.   return fenceEndPosition != [0,0]
  75. endfunction
  76.  
  77. function! s:FoldText()
  78.  
  79.  
  80.    "get first non-blank line
  81.     let fs = v:foldstart
  82.     while getline(fs) =~ '^\s*$' | let fs = nextnonblank(fs + 1)
  83.     endwhile
  84.     if fs > v:foldend
  85.         let line = getline(v:foldstart)
  86.     else
  87.         let line = substitute(getline(fs), '\t', repeat(' ', &tabstop), 'g')
  88.     endif
  89.  
  90.     let w = winwidth(0) - &foldcolumn - (&number ? 8 : 0)
  91.     let foldSize = 1 + v:foldend - v:foldstart
  92.  
  93.     let i = 0
  94.     let foldWords=0
  95.     let wordCount=0
  96.     while (i<line('$'))
  97.       let lineWords = len(split(getline(i)))
  98.       if (i<=v:foldend && i>= v:foldstart+1)
  99.         let foldWords = foldWords + lineWords
  100.       endif
  101.       let wordCount += lineWords
  102.       let i += 1
  103.     endwhile
  104.  
  105.     let foldWordsStr = " " . foldWords . " w"
  106.     let foldSizeStr = foldWordsStr"
  107.  "   let foldLevelStr = repeat("+--", v:foldlevel)
  108.  "   let foldPercentage = printf("[%.1f", (foldWords*1.0)/wordCount*100) . "%] "
  109.     let expansionString = repeat(".", w - strwidth(foldSizeStr.line))
  110.     return line . expansionString . foldSizeStr
  111.  
  112.  
  113. endfunction
  114.  
  115. " API {{{1
  116. function! ToggleMarkdownFoldexpr()
  117.   if &l:foldexpr ==# 'StackedMarkdownFolds()'
  118.     setlocal foldexpr=NestedMarkdownFolds()
  119.   else
  120.     setlocal foldexpr=StackedMarkdownFolds()
  121.   endif
  122. endfunction
  123. command! -buffer FoldToggle call ToggleMarkdownFoldexpr()
  124.  
  125. " Setup {{{1
  126. if !exists('g:markdown_fold_style')
  127.   let g:markdown_fold_style = 'stacked'
  128. endif
  129.  
  130. if !exists('g:markdown_fold_override_foldtext')
  131.   let g:markdown_fold_override_foldtext = 1
  132. endif
  133.  
  134. setlocal foldmethod=expr
  135.  
  136. if g:markdown_fold_override_foldtext
  137.   let &l:foldtext = s:SID() . 'FoldText()'
  138. endif
  139.  
  140. let &l:foldexpr =
  141.   \ g:markdown_fold_style ==# 'nested'
  142.   \ ? 'NestedMarkdownFolds()'
  143.   \ : 'StackedMarkdownFolds()'
  144.  
  145. "Teardown {{{1
  146. let b:undo_ftplugin .= '
  147.  \ | setlocal foldmethod< foldtext< foldexpr<
  148.  \ | delcommand FoldToggle
  149.  \ '
  150. " vim:set fdm=marker:
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top