Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 1 | " Author: Antony Lee <anntzer.lee@gmail.com> |
| 2 | " Description: Helper functions for reStructuredText syntax folding |
Bram Moolenaar | 4c05fa0 | 2019-01-01 15:32:17 +0100 | [diff] [blame] | 3 | " Last Modified: 2018-12-29 |
Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 4 | |
| 5 | function s:CacheRstFold() |
Bram Moolenaar | 4c05fa0 | 2019-01-01 15:32:17 +0100 | [diff] [blame] | 6 | if !g:rst_fold_enabled |
| 7 | return |
| 8 | endif |
| 9 | |
Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 10 | let closure = {'header_types': {}, 'max_level': 0, 'levels': {}} |
| 11 | function closure.Process(match) dict |
| 12 | let curline = getcurpos()[1] |
| 13 | if has_key(self.levels, curline - 1) |
| 14 | " For over+under-lined headers, the regex will match both at the |
| 15 | " overline and at the title itself; in that case, skip the second match. |
| 16 | return |
| 17 | endif |
| 18 | let lines = split(a:match, '\n') |
| 19 | let key = repeat(lines[-1][0], len(lines)) |
| 20 | if !has_key(self.header_types, key) |
| 21 | let self.max_level += 1 |
| 22 | let self.header_types[key] = self.max_level |
| 23 | endif |
| 24 | let self.levels[curline] = self.header_types[key] |
| 25 | endfunction |
| 26 | let save_cursor = getcurpos() |
Bram Moolenaar | 4c05fa0 | 2019-01-01 15:32:17 +0100 | [diff] [blame] | 27 | let save_mark = getpos("'[") |
Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 28 | silent keeppatterns %s/\v^%(%(([=`:.'"~^_*+#-])\1+\n)?.{1,2}\n([=`:.'"~^_*+#-])\2+)|%(%(([=`:.''"~^_*+#-])\3{2,}\n)?.{3,}\n([=`:.''"~^_*+#-])\4{2,})$/\=closure.Process(submatch(0))/gn |
| 29 | call setpos('.', save_cursor) |
Bram Moolenaar | 4c05fa0 | 2019-01-01 15:32:17 +0100 | [diff] [blame] | 30 | call setpos("'[", save_mark) |
Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 31 | let b:RstFoldCache = closure.levels |
| 32 | endfunction |
| 33 | |
| 34 | function RstFold#GetRstFold() |
Bram Moolenaar | 4c05fa0 | 2019-01-01 15:32:17 +0100 | [diff] [blame] | 35 | if !g:rst_fold_enabled |
| 36 | return |
| 37 | endif |
| 38 | |
Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 39 | if !has_key(b:, 'RstFoldCache') |
| 40 | call s:CacheRstFold() |
| 41 | endif |
| 42 | if has_key(b:RstFoldCache, v:lnum) |
| 43 | return '>' . b:RstFoldCache[v:lnum] |
| 44 | else |
| 45 | return '=' |
| 46 | endif |
| 47 | endfunction |
| 48 | |
| 49 | function RstFold#GetRstFoldText() |
Bram Moolenaar | 4c05fa0 | 2019-01-01 15:32:17 +0100 | [diff] [blame] | 50 | if !g:rst_fold_enabled |
| 51 | return |
| 52 | endif |
| 53 | |
Bram Moolenaar | 91f84f6 | 2018-07-29 15:07:52 +0200 | [diff] [blame] | 54 | if !has_key(b:, 'RstFoldCache') |
| 55 | call s:CacheRstFold() |
| 56 | endif |
| 57 | let indent = repeat(' ', b:RstFoldCache[v:foldstart] - 1) |
| 58 | let thisline = getline(v:foldstart) |
| 59 | " For over+under-lined headers, skip the overline. |
| 60 | let text = thisline =~ '^\([=`:.''"~^_*+#-]\)\1\+$' ? getline(v:foldstart + 1) : thisline |
| 61 | return indent . text |
| 62 | endfunction |