]> git.madduck.net Git - etc/vim.git/blob - after/ftplugin/markdown.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

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.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

:Toc should accept single `=` and `-` as setex header
[etc/vim.git] / after / ftplugin / markdown.vim
1 " folding for Markdown headers, both styles (atx- and setex-)
2 " http://daringfireball.net/projects/markdown/syntax#header
3 "
4 " this code can be placed in file
5 "   $HOME/.vim/after/ftplugin/markdown.vim
6 "
7 " original version from Steve Losh's gist: https://gist.github.com/1038710
8
9 function! s:is_mkdCode(lnum)
10     let name = synIDattr(synID(a:lnum, 1, 0), 'name')
11     return (name =~ '^mkd\%(Code$\|Snippet\)' || name != '' && name !~ '^\%(mkd\|html\)')
12 endfunction
13
14 if get(g:, "vim_markdown_folding_style_pythonic", 0)
15     function! Foldexpr_markdown(lnum)
16         let l2 = getline(a:lnum+1)
17         if  l2 =~ '^==\+\s*' && !s:is_mkdCode(a:lnum+1)
18             " next line is underlined (level 1)
19             return '>0'
20         elseif l2 =~ '^--\+\s*' && !s:is_mkdCode(a:lnum+1)
21             " next line is underlined (level 2)
22             return '>1'
23         endif
24
25         let l1 = getline(a:lnum)
26         if l1 =~ '^#' && !s:is_mkdCode(a:lnum)
27             " current line starts with hashes
28             return '>'.(matchend(l1, '^#\+') - 1)
29         elseif a:lnum == 1
30             " fold any 'preamble'
31             return '>1'
32         else
33             " keep previous foldlevel
34             return '='
35         endif
36     endfunction
37
38     function! Foldtext_markdown()
39         let line = getline(v:foldstart)
40         let has_numbers = &number || &relativenumber
41         let nucolwidth = &fdc + has_numbers * &numberwidth
42         let windowwidth = winwidth(0) - nucolwidth - 6
43         let foldedlinecount = v:foldend - v:foldstart
44         let line = strpart(line, 0, windowwidth - 2 -len(foldedlinecount))
45         let line = substitute(line, '\%("""\|''''''\)', '', '')
46         let fillcharcount = windowwidth - len(line) - len(foldedlinecount) + 1
47         return line . ' ' . repeat("-", fillcharcount) . ' ' . foldedlinecount
48     endfunction
49 else
50     function! Foldexpr_markdown(lnum)
51         if (a:lnum == 1)
52             let l0 = ''
53         else
54             let l0 = getline(a:lnum-1)
55         endif
56         " keep track of fenced code blocks
57         if l0 =~ '````*' || l0 =~ '~~~~*'
58             if b:fenced_block == 0
59                 let b:fenced_block = 1
60             elseif b:fenced_block == 1
61                 let b:fenced_block = 0
62             endif
63         endif
64
65         let l2 = getline(a:lnum+1)
66         if  l2 =~ '^==\+\s*' && !s:is_mkdCode(a:lnum+1)
67             " next line is underlined (level 1)
68             return '>1'
69         elseif l2 =~ '^--\+\s*' && !s:is_mkdCode(a:lnum+1)
70             " next line is underlined (level 2)
71             if g:vim_markdown_folding_level == 2
72                 return '>1'
73             else
74                 return '>2'
75             endif
76         endif
77
78         let l1 = getline(a:lnum)
79         if l1 =~ '^#' && !s:is_mkdCode(a:lnum)
80             " fold level according to option
81             let l:level = matchend(l1, '^#\+')
82             if g:vim_markdown_folding_level == 1 || l:level > g:vim_markdown_folding_level
83                 return -1
84             else
85                 " code blocks are always folded
86                 return b:fenced_block
87             endif
88         endif
89
90         if l0 =~ '^#' && !s:is_mkdCode(a:lnum-1)
91             " collapse comments in fenced code blocks into a single fold
92             if b:fenced_block == 1
93                 return 1
94             endif
95             " current line starts with hashes
96             return '>'.matchend(l0, '^#\+')
97         else
98             " fold here because of setext headers
99             return '='
100         endif
101     endfunction
102 endif
103
104
105 let b:fenced_block = 0
106 let g:vim_markdown_folding_level = get(g:, "vim_markdown_folding_level", 1)
107
108 if !get(g:, "vim_markdown_folding_disabled", 0)
109     setlocal foldexpr=Foldexpr_markdown(v:lnum)
110     setlocal foldmethod=expr
111     if get(g:, "vim_markdown_folding_style_pythonic", 0)
112         setlocal foldtext=Foldtext_markdown()
113     endif
114 endif