-
Notifications
You must be signed in to change notification settings - Fork 0
/
.vimfolding.txt
121 lines (107 loc) · 2.98 KB
/
.vimfolding.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
" 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()
let level = HeadingDepth(v:foldstart)
let indent = repeat('#', level)
let title = substitute(getline(v:foldstart), '^#\+\s*', '', '')
let foldsize = (v:foldend - v:foldstart)
let linecount = '['.foldsize.' line'.(foldsize>1?'s':'').']'
return indent.' '.title.' '.linecount
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: