diff options
Diffstat (limited to 'autoload/vimtex/fold')
-rw-r--r-- | autoload/vimtex/fold/cmd_addplot.vim | 51 | ||||
-rw-r--r-- | autoload/vimtex/fold/cmd_multi.vim | 51 | ||||
-rw-r--r-- | autoload/vimtex/fold/cmd_single.vim | 52 | ||||
-rw-r--r-- | autoload/vimtex/fold/cmd_single_opt.vim | 53 | ||||
-rw-r--r-- | autoload/vimtex/fold/comments.vim | 46 | ||||
-rw-r--r-- | autoload/vimtex/fold/env_options.vim | 53 | ||||
-rw-r--r-- | autoload/vimtex/fold/envs.vim | 188 | ||||
-rw-r--r-- | autoload/vimtex/fold/markers.vim | 60 | ||||
-rw-r--r-- | autoload/vimtex/fold/preamble.vim | 36 | ||||
-rw-r--r-- | autoload/vimtex/fold/sections.vim | 180 |
10 files changed, 770 insertions, 0 deletions
diff --git a/autoload/vimtex/fold/cmd_addplot.vim b/autoload/vimtex/fold/cmd_addplot.vim new file mode 100644 index 00000000..9e997681 --- /dev/null +++ b/autoload/vimtex/fold/cmd_addplot.vim @@ -0,0 +1,51 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#cmd_addplot#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config).init() +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'cmd_addplot', + \ 're' : {}, + \ 'opened' : 0, + \ 'cmds' : [], + \} +function! s:folder.init() abort dict " {{{1 + let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\s*%(\[[^\]]*\])?' + + let self.re.start = l:re . '\s*\w+\s*%(\[[^\]]*\])?\s*\ze\{\s*%($|\%)' + let self.re.end = '^\s*}' + let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')' + + return self +endfunction + +" }}}1 +function! s:folder.level(line, lnum) abort dict " {{{1 + if a:line =~# self.re.start + let self.opened = 1 + return 'a1' + elseif self.opened && a:line =~# self.re.end + let self.opened = 0 + return 's1' + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + return matchstr(a:line, self.re.start) . '{...}' + \ . substitute(getline(v:foldend), self.re.end, '', '') +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/cmd_multi.vim b/autoload/vimtex/fold/cmd_multi.vim new file mode 100644 index 00000000..cb84d09e --- /dev/null +++ b/autoload/vimtex/fold/cmd_multi.vim @@ -0,0 +1,51 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#cmd_multi#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config).init() +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'cmd_multi', + \ 're' : {}, + \ 'opened' : 0, + \ 'cmds' : [], + \} +function! s:folder.init() abort dict " {{{1 + let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\*?' + + let self.re.start = l:re . '.*(\{|\[)\s*(\%.*)?$' + let self.re.end = '\v^\s*%(\}\s*\{)*\}\s*%(\%|$)' + let self.re.text = l:re . '\{[^}]*\}' + let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')' + + return self +endfunction + +" }}}1 +function! s:folder.level(line, lnum) abort dict " {{{1 + if a:line =~# self.re.start + let self.opened += 1 + return 'a1' + elseif self.opened > 0 && a:line =~# self.re.end + let self.opened -= 1 + return 's1' + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + return a:line +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/cmd_single.vim b/autoload/vimtex/fold/cmd_single.vim new file mode 100644 index 00000000..1403ad9b --- /dev/null +++ b/autoload/vimtex/fold/cmd_single.vim @@ -0,0 +1,52 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#cmd_single#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config).init() +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'cmd_single', + \ 're' : {}, + \ 'opened' : 0, + \ 'cmds' : [], + \} +function! s:folder.init() abort dict " {{{1 + let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\*?\s*%(\[.*\])?' + + let self.re.start = l:re . '\s*\{\s*%($|\%)' + let self.re.end = '^\s*}' + let self.re.text = l:re + let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')' + + return self +endfunction + +" }}}1 +function! s:folder.level(line, lnum) abort dict " {{{1 + if a:line =~# self.re.start + let self.opened = 1 + return 'a1' + elseif self.opened && a:line =~# self.re.end + let self.opened = 0 + return 's1' + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + return matchstr(a:line, self.re.text) . '{...}' + \ . substitute(getline(v:foldend), self.re.end, '', '') +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/cmd_single_opt.vim b/autoload/vimtex/fold/cmd_single_opt.vim new file mode 100644 index 00000000..8def0234 --- /dev/null +++ b/autoload/vimtex/fold/cmd_single_opt.vim @@ -0,0 +1,53 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#cmd_single_opt#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config).init() +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'cmd_single_opt', + \ 're' : {}, + \ 'opened' : 0, + \ 'cmds' : [], + \} +function! s:folder.init() abort dict " {{{1 + let l:re = '\v^\s*\\%(' . join(self.cmds, '|') . ')\*?' + + let self.re.start = l:re . '\s*\[\s*%($|\%)' + let self.re.end = '^\s*\]{' + let self.re.text = l:re + let self.re.fold_re = '\\%(' . join(self.cmds, '|') . ')' + + return self +endfunction + +" }}}1 +function! s:folder.level(line, lnum) abort dict " {{{1 + if a:line =~# self.re.start + let self.opened = 1 + return 'a1' + elseif self.opened && a:line =~# self.re.end + let self.opened = 0 + return 's1' + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + let l:col = strlen(matchstr(a:line, '^\s*')) + 1 + return matchstr(a:line, self.re.text) . '[...]{' + \ . vimtex#cmd#get_at(v:foldstart, l:col).args[0].text . '}' +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/comments.vim b/autoload/vimtex/fold/comments.vim new file mode 100644 index 00000000..4a313064 --- /dev/null +++ b/autoload/vimtex/fold/comments.vim @@ -0,0 +1,46 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#comments#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config) +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'comments', + \ 're' : {'start' : '^\s*%'}, + \ 'opened' : 0, + \} +function! s:folder.level(line, lnum) abort dict " {{{1 + if exists('b:vimtex.fold_types_dict.markers.opened') + \ && b:vimtex.fold_types_dict.markers.opened | return | endif + + if a:line =~# self.re.start + let l:next = getline(a:lnum-1) !~# self.re.start + let l:prev = getline(a:lnum+1) !~# self.re.start + if l:next && !l:prev + let self.opened = 1 + return 'a1' + elseif l:prev && !l:next + let self.opened = 0 + return 's1' + endif + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + let l:lines = map(getline(v:foldstart, v:foldend), 'matchstr(v:val, ''%\s*\zs.*\ze\s*'')') + return matchstr(a:line, '^.*\s*%') . join(l:lines, ' ') +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/env_options.vim b/autoload/vimtex/fold/env_options.vim new file mode 100644 index 00000000..eab339bf --- /dev/null +++ b/autoload/vimtex/fold/env_options.vim @@ -0,0 +1,53 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#env_options#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config) +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'envs with options', + \ 're' : { + \ 'start' : g:vimtex#re#not_comment . '\\begin\s*\{.{-}\}\[\s*($|\%)', + \ 'end' : '\s*\]\s*$', + \ }, + \ 'opened' : 0, + \} +function! s:folder.level(line, lnum) abort dict " {{{1 + return self.opened + \ ? self.fold_closed(a:line, a:lnum) + \ : self.fold_opened(a:line, a:lnum) +endfunction + +" }}}1 +function! s:folder.fold_opened(line, lnum) abort dict " {{{1 + if a:line =~# self.re.start + let self.opened = 1 + return 'a1' + endif +endfunction + +" }}}1 +function! s:folder.fold_closed(line, lnum) abort dict " {{{1 + if a:line =~# self.re.end + let self.opened = 0 + return 's1' + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + return a:line . '...] ' +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/envs.vim b/autoload/vimtex/fold/envs.vim new file mode 100644 index 00000000..1eb70f3c --- /dev/null +++ b/autoload/vimtex/fold/envs.vim @@ -0,0 +1,188 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#envs#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config).init() +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'environments', + \ 're' : { + \ 'start' : g:vimtex#re#not_comment . '\\begin\s*\{.{-}\}', + \ 'end' : g:vimtex#re#not_comment . '\\end\s*\{.{-}\}', + \ 'name' : g:vimtex#re#not_comment . '\\%(begin|end)\s*\{\zs.{-}\ze\}' + \ }, + \ 'whitelist' : [], + \ 'blacklist' : [], + \} +function! s:folder.init() abort dict " {{{1 + " Define the validator as simple as possible + if empty(self.whitelist) && empty(self.blacklist) + function! self.validate(env) abort dict + return 1 + endfunction + elseif empty(self.whitelist) + function! self.validate(env) abort dict + return index(self.blacklist, a:env) < 0 + endfunction + elseif empty(self.blacklist) + function! self.validate(env) abort dict + return index(self.whitelist, a:env) >= 0 + endfunction + else + function! self.validate(env) abort dict + return index(self.whitelist, a:env) >= 0 && index(self.blacklist, a:env) < 0 + endfunction + endif + + return self +endfunction + +" }}}1 +function! s:folder.level(line, lnum) abort dict " {{{1 + let l:env = matchstr(a:line, self.re.name) + + if !empty(l:env) && self.validate(l:env) + if a:line =~# self.re.start + if a:line !~# '\\end' + return 'a1' + endif + elseif a:line =~# self.re.end + if a:line !~# '\\begin' + return 's1' + endif + endif + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + let env = matchstr(a:line, self.re.name) + if !self.validate(env) | return | endif + + " Set caption/label based on type of environment + if env ==# 'frame' + let label = '' + let caption = self.parse_caption_frame(a:line) + elseif env ==# 'table' + let label = self.parse_label() + let caption = self.parse_caption_table(a:line) + else + let label = self.parse_label() + let caption = self.parse_caption(a:line) + endif + + let width_ind = len(matchstr(a:line, '^\s*')) + let width = winwidth(0) - (&number ? &numberwidth : 0) - 4 - width_ind + + let width_env = 19 + let width_lab = len(label) + 2 > width - width_env + \ ? width - width_env + \ : len(label) + 2 + let width_cap = width - width_env - width_lab + + if !empty(label) + let label = printf('(%.*S)', width_lab, label) + endif + + if !empty(caption) + if strchars(caption) > width_cap + let caption = strpart(caption, 0, width_cap - 4) . '...' + endif + else + let width_env += width_cap + let width_cap = 0 + endif + + if strlen(env) > width_env - 8 + let env = strpart(env, 0, width_env - 11) . '...' + endif + let env = '\begin{' . env . '}' + + let title = printf('%*S%-*S %-*S %*S', + \ width_ind, '', + \ width_env, env, + \ width_cap, caption, + \ width_lab, label) + + return substitute(title, '\s\+$', '', '') +endfunction + +" }}}1 +function! s:folder.parse_label() abort dict " {{{1 + let i = v:foldend + while i >= v:foldstart + if getline(i) =~# '^\s*\\label' + return matchstr(getline(i), '^\s*\\label\%(\[.*\]\)\?{\zs.*\ze}') + end + let i -= 1 + endwhile + return '' +endfunction + +" }}}1 +function! s:folder.parse_caption(line) abort dict " {{{1 + let i = v:foldend + while i >= v:foldstart + if getline(i) =~# '^\s*\\caption' + return matchstr(getline(i), + \ '^\s*\\caption\(\[.*\]\)\?{\zs.\{-1,}\ze\(}\s*\)\?$') + end + let i -= 1 + endwhile + + " If no caption found, check for a caption comment + return matchstr(a:line,'\\begin\*\?{.*}\s*%\s*\zs.*') +endfunction + +" }}}1 +function! s:folder.parse_caption_table(line) abort dict " {{{1 + let i = v:foldstart + while i <= v:foldend + if getline(i) =~# '^\s*\\caption' + return matchstr(getline(i), + \ '^\s*\\caption\s*\(\[.*\]\)\?\s*{\zs.\{-1,}\ze\(}\s*\)\?$') + end + let i += 1 + endwhile + + " If no caption found, check for a caption comment + return matchstr(a:line,'\\begin\*\?{.*}\s*%\s*\zs.*') +endfunction + +" }}}1 +function! s:folder.parse_caption_frame(line) abort dict " {{{1 + " Test simple variants first + let caption1 = matchstr(a:line,'\\begin\*\?{.*}\(\[[^]]*\]\)\?{\zs.\+\ze}') + let caption2 = matchstr(a:line,'\\begin\*\?{.*}\(\[[^]]*\]\)\?{\zs.\+') + if !empty(caption1) + return caption1 + elseif !empty(caption2) + return caption2 + endif + + " Search for \frametitle command + let i = v:foldstart + while i <= v:foldend + if getline(i) =~# '^\s*\\frametitle' + return matchstr(getline(i), + \ '^\s*\\frametitle\(\[.*\]\)\?{\zs.\{-1,}\ze\(}\s*\)\?$') + end + let i += 1 + endwhile + + " If no caption found, check for a caption comment + return matchstr(a:line,'\\begin\*\?{.*}\s*%\s*\zs.*') +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/markers.vim b/autoload/vimtex/fold/markers.vim new file mode 100644 index 00000000..00aa1fce --- /dev/null +++ b/autoload/vimtex/fold/markers.vim @@ -0,0 +1,60 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#markers#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config).init() +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'markers', + \ 'open' : '{{{', + \ 'close' : '}}}', + \ 're' : {}, + \ 'opened' : 0, + \} +function! s:folder.init() abort dict " {{{1 + let self.re.start = '%.*' . self.open + let self.re.end = '%.*' . self.close + let self.re.text = [ + \ [self.re.start . '\d\?\s*\zs.*', '% ' . self.open . ' '], + \ ['%\s*\zs.*\ze' . self.open, '% ' . self.open . ' '], + \ ['^.*\ze\s*%', ''], + \] + + let self.re.fold_re = escape(self.open . '|' . self.close, '{}%+*.') + + return self +endfunction + +" }}}1 +function! s:folder.level(line, lnum) abort dict " {{{1 + if a:line =~# self.re.start + let s:self.opened = 1 + return 'a1' + elseif a:line =~# self.re.end + let s:self.opened = 0 + return 's1' + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + for [l:re, l:pre] in self.re.text + let l:text = matchstr(a:line, l:re) + if !empty(l:text) | return l:pre . l:text | endif + endfor + + return '% ' . self.open . ' ' . getline(v:foldstart + 1) +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/preamble.vim b/autoload/vimtex/fold/preamble.vim new file mode 100644 index 00000000..434064ee --- /dev/null +++ b/autoload/vimtex/fold/preamble.vim @@ -0,0 +1,36 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#preamble#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config) +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'preamble', + \ 're' : { + \ 'start' : '^\s*\\documentclass', + \ 'fold_re' : '\\documentclass', + \ }, + \} +function! s:folder.level(line, lnum) abort dict " {{{1 + if a:line =~# self.re.start + return '>1' + endif +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + return ' Preamble' +endfunction + +" }}}1 + +endif diff --git a/autoload/vimtex/fold/sections.vim b/autoload/vimtex/fold/sections.vim new file mode 100644 index 00000000..2929a728 --- /dev/null +++ b/autoload/vimtex/fold/sections.vim @@ -0,0 +1,180 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 + +" vimtex - LaTeX plugin for Vim +" +" Maintainer: Karl Yngve Lervåg +" Email: karl.yngve@gmail.com +" + +function! vimtex#fold#sections#new(config) abort " {{{1 + return extend(deepcopy(s:folder), a:config).init() +endfunction + +" }}}1 + + +let s:folder = { + \ 'name' : 'sections', + \ 'parse_levels' : 0, + \ 're' : {}, + \ 'folds' : [], + \ 'sections' : [], + \ 'parts' : [], + \ 'time' : 0, + \} +function! s:folder.init() abort dict " {{{1 + let self.re.parts = '\v^\s*\\%(' . join(self.parts, '|') . ')' + let self.re.sections = '\v^\s*\\%(' . join(self.sections, '|') . ')' + let self.re.fake_sections = '\v^\s*\% Fake%(' + \ . join(self.sections, '|') . ').*' + let self.re.any_sections = '\v^\s*%(\\|\% Fake)%(' + \ . join(self.sections, '|') . ').*' + + let self.re.start = self.re.parts + \ . '|' . self.re.sections + \ . '|' . self.re.fake_sections + + let self.re.secpat1 = self.re.sections . '\*?\s*\{\zs.*' + let self.re.secpat2 = self.re.sections . '\*?\s*\[\zs.*' + + let self.re.fold_re = '\\%(' . join(self.parts + self.sections, '|') . ')' + + return self +endfunction + +" }}}1 +function! s:folder.level(line, lnum) abort dict " {{{1 + call self.refresh() + + " Fold chapters and sections + for [l:part, l:level] in self.folds + if a:line =~# l:part + return '>' . l:level + endif + endfor +endfunction + +" }}}1 +function! s:folder.text(line, level) abort dict " {{{1 + if a:line =~# '\\frontmatter' + let l:title = 'Frontmatter' + elseif a:line =~# '\\mainmatter' + let l:title = 'Mainmatter' + elseif a:line =~# '\\backmatter' + let l:title = 'Backmatter' + elseif a:line =~# '\\appendix' + let l:title = 'Appendix' + elseif a:line =~# self.re.secpat1 + let l:title = self.parse_title(matchstr(a:line, self.re.secpat1), 0) + elseif a:line =~# self.re.secpat2 + let l:title = self.parse_title(matchstr(a:line, self.re.secpat2), 1) + elseif a:line =~# self.re.fake_sections + let l:title = matchstr(a:line, self.re.fake_sections) + endif + + let l:level = self.parse_level(v:foldstart, a:level) + + return printf('%-5s %-s', l:level, + \ substitute(strpart(l:title, 0, winwidth(0) - 7), '\s\+$', '', '')) +endfunction + +" }}}1 +function! s:folder.parse_level(lnum, level) abort dict " {{{1 + if !self.parse_levels | return a:level | endif + + if !has_key(self, 'toc') + let self.toc = vimtex#toc#new({ + \ 'name' : 'Fold text ToC', + \ 'layers' : ['content'], + \ 'refresh_always' : 0, + \}) + let self.toc_updated = 0 + let self.file_updated = {} + endif + + let l:file = expand('%') + let l:ftime = getftime(l:file) + + if l:ftime > get(self.file_updated, l:file) + \ || localtime() > self.toc_updated + 300 + call self.toc.get_entries(1) + let self.toc_entries = filter( + \ self.toc.get_visible_entries(), + \ '!empty(v:val.number)') + let self.file_updated[l:file] = l:ftime + let self.toc_updated = localtime() + endif + + let l:entries = filter(deepcopy(self.toc_entries), 'v:val.line == a:lnum') + if len(l:entries) > 1 + call filter(l:entries, "v:val.file ==# expand('%:p')") + endif + + return empty(l:entries) ? '' : self.toc.print_number(l:entries[0].number) +endfunction + +" }}}1 +function! s:folder.parse_title(string, type) abort dict " {{{1 + let l:idx = -1 + let l:length = strlen(a:string) + let l:level = 1 + while l:level >= 1 + let l:idx += 1 + if l:idx > l:length + break + elseif a:string[l:idx] ==# ['}',']'][a:type] + let l:level -= 1 + elseif a:string[l:idx] ==# ['{','['][a:type] + let l:level += 1 + endif + endwhile + let l:parsed = strpart(a:string, 0, l:idx) + return empty(l:parsed) + \ ? '<untitled>' : l:parsed +endfunction + +" }}}1 +function! s:folder.refresh() abort dict " {{{1 + " + " Parse current buffer to find which sections to fold and their levels. The + " patterns are predefined to optimize the folding. + " + " We ignore top level parts such as \frontmatter, \appendix, \part, and + " similar, unless there are at least two such commands in a document. + " + + " Only refresh if file has been changed + let l:time = getftime(expand('%')) + if l:time == self.time | return | endif + let self.time = l:time + + " Initialize + let self.folds = [] + let level = 0 + let buffer = getline(1,'$') + + " Parse part commands (frontmatter, appendix, etc) + " Note: We want a minimum of two top level parts + let lines = filter(copy(buffer), 'v:val =~ ''' . self.re.parts . '''') + if len(lines) >= 2 + let level += 1 + call insert(self.folds, [self.re.parts, level]) + endif + + " Parse section commands (part, chapter, [sub...]section) + let lines = filter(copy(buffer), 'v:val =~ ''' . self.re.any_sections . '''') + for part in self.sections + let partpattern = '^\s*\%(\\\|% Fake\)' . part . ':\?\>' + for line in lines + if line =~# partpattern + let level += 1 + call insert(self.folds, [partpattern, level]) + break + endif + endfor + endfor +endfunction + +" }}}1 + +endif |