Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- " Fold expressions {{{1
- function! StackedMarkdownFolds()
- if HeadingDepth(v:lnum) > 0
- return ">1"
- else
- return "="
- endif
- endfunction
- function! NestedMarkdownFolds()
- let depth = HeadingDepth(v:lnum)
- if depth > 0
- return ">".depth
- else
- return "="
- endif
- endfunction
- " Helpers {{{1
- function! s:SID()
- return matchstr(expand('<sfile>'), '<SNR>\d\+_')
- endfunction
- function! HeadingDepth(lnum)
- let level=0
- let thisline = getline(a:lnum)
- let hashCount = len(matchstr(thisline, '^#\{1,6}'))
- if hashCount > 0
- let level = hashCount
- else
- if thisline != ''
- let nextline = getline(a:lnum + 1)
- if nextline =~ '^=\+\s*$'
- let level = 1
- elseif nextline =~ '^-\+\s*$'
- let level = 2
- endif
- endif
- endif
- if level > 0 && LineIsFenced(a:lnum)
- " Ignore # or === if they appear within fenced code blocks
- let level = 0
- endif
- return level
- endfunction
- function! LineIsFenced(lnum)
- if exists("b:current_syntax") && b:current_syntax ==# 'markdown'
- " It's cheap to check if the current line has 'markdownCode' syntax group
- return s:HasSyntaxGroup(a:lnum, 'markdownCode')
- else
- " Using searchpairpos() is expensive, so only do it if syntax highlighting
- " is not enabled
- return s:HasSurroundingFencemarks(a:lnum)
- endif
- endfunction
- function! s:HasSyntaxGroup(lnum, targetGroup)
- let syntaxGroup = map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")')
- for value in syntaxGroup
- if value =~ '\vmarkdown(Code|Highlight)'
- return 1
- endif
- endfor
- endfunction
- function! s:HasSurroundingFencemarks(lnum)
- let cursorPosition = [line("."), col(".")]
- call cursor(a:lnum, 1)
- let startFence = '\%^```\|^\n\zs```'
- let endFence = '```\n^$'
- let fenceEndPosition = searchpairpos(startFence,'',endFence,'W')
- call cursor(cursorPosition)
- return fenceEndPosition != [0,0]
- endfunction
- function! s:FoldText()
- "get first non-blank line
- let fs = v:foldstart
- while getline(fs) =~ '^\s*$' | let fs = nextnonblank(fs + 1)
- endwhile
- if fs > v:foldend
- let line = getline(v:foldstart)
- else
- let line = substitute(getline(fs), '\t', repeat(' ', &tabstop), 'g')
- endif
- let w = winwidth(0) - &foldcolumn - (&number ? 8 : 0)
- let foldSize = 1 + v:foldend - v:foldstart
- let i = 0
- let foldWords=0
- let wordCount=0
- while (i<line('$'))
- let lineWords = len(split(getline(i)))
- if (i<=v:foldend && i>= v:foldstart+1)
- let foldWords = foldWords + lineWords
- endif
- let wordCount += lineWords
- let i += 1
- endwhile
- let foldWordsStr = " " . foldWords . " w"
- let foldSizeStr = foldWordsStr"
- " let foldLevelStr = repeat("+--", v:foldlevel)
- " let foldPercentage = printf("[%.1f", (foldWords*1.0)/wordCount*100) . "%] "
- let expansionString = repeat(".", w - strwidth(foldSizeStr.line))
- return line . expansionString . foldSizeStr
- endfunction
- " API {{{1
- function! ToggleMarkdownFoldexpr()
- if &l:foldexpr ==# 'StackedMarkdownFolds()'
- setlocal foldexpr=NestedMarkdownFolds()
- else
- setlocal foldexpr=StackedMarkdownFolds()
- endif
- endfunction
- command! -buffer FoldToggle call ToggleMarkdownFoldexpr()
- " Setup {{{1
- if !exists('g:markdown_fold_style')
- let g:markdown_fold_style = 'stacked'
- endif
- if !exists('g:markdown_fold_override_foldtext')
- let g:markdown_fold_override_foldtext = 1
- endif
- setlocal foldmethod=expr
- if g:markdown_fold_override_foldtext
- let &l:foldtext = s:SID() . 'FoldText()'
- endif
- let &l:foldexpr =
- \ g:markdown_fold_style ==# 'nested'
- \ ? 'NestedMarkdownFolds()'
- \ : 'StackedMarkdownFolds()'
- "Teardown {{{1
- let b:undo_ftplugin .= '
- \ | setlocal foldmethod< foldtext< foldexpr<
- \ | delcommand FoldToggle
- \ '
- " vim:set fdm=marker:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement