All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
2 " folding for Markdown headers, both styles (atx- and setex-)
3 " http://daringfireball.net/projects/markdown/syntax#header
5 " this code can be placed in file
6 " $HOME/.vim/after/ftplugin/markdown.vim
8 " original version from Steve Losh's gist: https://gist.github.com/1038710
10 function! s:is_mkdCode(lnum)
11 let name = synIDattr(synID(a:lnum, 1, 0), 'name')
12 return (name =~ '^mkd\%(Code$\|Snippet\)' || name != '' && name !~ '^\%(mkd\|html\)')
15 if get(g:, "vim_markdown_folding_style_pythonic", 0)
16 function! Foldexpr_markdown(lnum)
17 let l1 = getline(a:lnum)
18 "~~~~~ keep track of fenced code blocks ~~~~~
19 "If we hit a code block fence
20 if l1 =~ '````*' || l1 =~ '\~\~\~\~*'
21 " toggle the variable that says if we're in a code block
22 if b:fenced_block == 0
23 let b:fenced_block = 1
24 elseif b:fenced_block == 1
25 let b:fenced_block = 0
27 " else, if we're caring about front matter
28 elseif g:vim_markdown_frontmatter == 1
29 " if we're in front matter and not on line 1
30 if b:front_matter == 1 && a:lnum > 2
31 let l0 = getline(a:lnum-1)
32 " if the previous line fenced front matter
34 " we must not be in front matter
35 let b:front_matter = 0
37 " else, if we're on line one
39 " if we hit a front matter fence
41 " we're in the front matter
42 let b:front_matter = 1
47 " if we're in a code block or front matter
48 if b:fenced_block == 1 || b:front_matter == 1
53 " keep previous foldlevel
58 let l2 = getline(a:lnum+1)
59 " if the next line starts with two or more '='
61 if l2 =~ '^==\+\s*' && !s:is_mkdCode(a:lnum+1)
62 " next line is underlined (level 1)
64 " else, if the nex line starts with two or more '-'
66 elseif l2 =~ '^--\+\s*' && !s:is_mkdCode(a:lnum+1)
67 " next line is underlined (level 2)
71 "if we're on a non-code line starting with a pound sign
72 if l1 =~ '^#' && !s:is_mkdCode(a:lnum)
73 " set the fold level to the number of hashes -1
74 " return '>'.(matchend(l1, '^#\+') - 1)
75 " set the fold level to the number of hashes
76 return '>'.(matchend(l1, '^#\+'))
77 " else, if we're on line 1
82 " keep previous foldlevel
87 function! Foldtext_markdown()
88 let line = getline(v:foldstart)
89 let has_numbers = &number || &relativenumber
90 let nucolwidth = &fdc + has_numbers * &numberwidth
91 let windowwidth = winwidth(0) - nucolwidth - 6
92 let foldedlinecount = v:foldend - v:foldstart
93 let line = strpart(line, 0, windowwidth - 2 -len(foldedlinecount))
94 let line = substitute(line, '\%("""\|''''''\)', '', '')
95 let fillcharcount = windowwidth - len(line) - len(foldedlinecount) + 1
96 return line . ' ' . repeat("-", fillcharcount) . ' ' . foldedlinecount
98 else " vim_markdown_folding_style_pythonic == 0
99 function! Foldexpr_markdown(lnum)
103 let l0 = getline(a:lnum-1)
106 " keep track of fenced code blocks
107 if l0 =~ '````*' || l0 =~ '\~\~\~\~*'
108 if b:fenced_block == 0
109 let b:fenced_block = 1
110 elseif b:fenced_block == 1
111 let b:fenced_block = 0
113 elseif g:vim_markdown_frontmatter == 1
114 if b:front_matter == 1
116 let b:front_matter = 0
120 let b:front_matter = 1
125 if b:fenced_block == 1 || b:front_matter == 1
126 " keep previous foldlevel
130 let l2 = getline(a:lnum+1)
131 if l2 =~ '^==\+\s*' && !s:is_mkdCode(a:lnum+1)
132 " next line is underlined (level 1)
134 elseif l2 =~ '^--\+\s*' && !s:is_mkdCode(a:lnum+1)
135 " next line is underlined (level 2)
136 if s:vim_markdown_folding_level >= 2
143 let l1 = getline(a:lnum)
144 if l1 =~ '^#' && !s:is_mkdCode(a:lnum)
145 " fold level according to option
146 if s:vim_markdown_folding_level == 1 || matchend(l1, '^#\+') > s:vim_markdown_folding_level
147 if a:lnum == line('$')
148 return matchend(l1, '^#\+') - 1
153 " headers are not folded
158 if l0 =~ '^#' && !s:is_mkdCode(a:lnum-1)
159 " previous line starts with hashes
160 return '>'.matchend(l0, '^#\+')
162 " keep previous foldlevel
169 let b:fenced_block = 0
170 let b:front_matter = 0
171 let s:vim_markdown_folding_level = get(g:, "vim_markdown_folding_level", 1)
173 function! s:MarkdownSetupFolding()
174 if !get(g:, "vim_markdown_folding_disabled", 0)
175 if get(g:, "vim_markdown_folding_style_pythonic", 0)
176 if get(g:, "vim_markdown_override_foldtext", 1)
177 setlocal foldtext=Foldtext_markdown()
180 setlocal foldexpr=Foldexpr_markdown(v:lnum)
181 setlocal foldmethod=expr
185 function! s:MarkdownSetupFoldLevel()
186 if get(g:, "vim_markdown_folding_style_pythonic", 0)
187 " set default foldlevel
188 execute "setlocal foldlevel=".s:vim_markdown_folding_level
192 call s:MarkdownSetupFoldLevel()
193 call s:MarkdownSetupFolding()
196 " These autocmds need to be kept in sync with the autocmds calling
197 " s:MarkdownRefreshSyntax in ftplugin/markdown.vim.
198 autocmd BufWinEnter,BufWritePost <buffer> call s:MarkdownSetupFolding()
199 autocmd InsertEnter,InsertLeave <buffer> call s:MarkdownSetupFolding()
200 autocmd CursorHold,CursorHoldI <buffer> call s:MarkdownSetupFolding()