diff options
Diffstat (limited to 'autoload/vimtex/toc.vim')
-rw-r--r-- | autoload/vimtex/toc.vim | 802 |
1 files changed, 0 insertions, 802 deletions
diff --git a/autoload/vimtex/toc.vim b/autoload/vimtex/toc.vim deleted file mode 100644 index bb2d7ffb..00000000 --- a/autoload/vimtex/toc.vim +++ /dev/null @@ -1,802 +0,0 @@ -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#toc#init_buffer() abort " {{{1 - if !g:vimtex_toc_enabled | return | endif - - command! -buffer VimtexTocOpen call b:vimtex.toc.open() - command! -buffer VimtexTocToggle call b:vimtex.toc.toggle() - - nnoremap <buffer> <plug>(vimtex-toc-open) :call b:vimtex.toc.open()<cr> - nnoremap <buffer> <plug>(vimtex-toc-toggle) :call b:vimtex.toc.toggle()<cr> -endfunction - -" }}}1 -function! vimtex#toc#init_state(state) abort " {{{1 - if !g:vimtex_toc_enabled | return | endif - - let a:state.toc = vimtex#toc#new() -endfunction - -" }}}1 - -function! vimtex#toc#new(...) abort " {{{1 - return extend( - \ deepcopy(s:toc), - \ vimtex#util#extend_recursive( - \ deepcopy(g:vimtex_toc_config), - \ a:0 > 0 ? a:1 : {})) -endfunction - -" }}}1 -function! vimtex#toc#get_entries() abort " {{{1 - if !has_key(b:vimtex, 'toc') | return [] | endif - - return b:vimtex.toc.get_entries(0) -endfunction - -" }}}1 -function! vimtex#toc#refresh() abort " {{{1 - if has_key(b:vimtex, 'toc') - call b:vimtex.toc.get_entries(1) - endif -endfunction - -" }}}1 - -let s:toc = {} - -" -" Open and close TOC window -" -function! s:toc.open() abort dict " {{{1 - if self.is_open() | return | endif - - if has_key(self, 'layers') - for l:key in keys(self.layer_status) - let self.layer_status[l:key] = index(self.layers, l:key) >= 0 - endfor - endif - - let self.calling_file = expand('%:p') - let self.calling_line = line('.') - - call self.get_entries(0) - - if self.mode > 1 - call setloclist(0, map(filter(deepcopy(self.entries), 'v:val.active'), '{ - \ ''lnum'': v:val.line, - \ ''filename'': v:val.file, - \ ''text'': v:val.title, - \}')) - try - call setloclist(0, [], 'r', {'title': self.name}) - catch - endtry - if self.mode == 4 | lopen | endif - endif - - if self.mode < 3 - call self.create() - endif -endfunction - -" }}}1 -function! s:toc.is_open() abort dict " {{{1 - return bufwinnr(bufnr(self.name)) >= 0 -endfunction - -" }}}1 -function! s:toc.toggle() abort dict " {{{1 - if self.is_open() - call self.close() - else - call self.open() - if has_key(self, 'prev_winid') - call win_gotoid(self.prev_winid) - endif - endif -endfunction - -" }}}1 -function! s:toc.close() abort dict " {{{1 - let self.fold_level = &l:foldlevel - - if self.resize - silent exe 'set columns -=' . self.split_width - endif - - if self.split_pos ==# 'full' - silent execute 'buffer' self.prev_bufnr - else - silent execute 'bwipeout' bufnr(self.name) - endif -endfunction - -" }}}1 -function! s:toc.goto() abort dict " {{{1 - if self.is_open() - let l:prev_winid = win_getid() - silent execute bufwinnr(bufnr(self.name)) . 'wincmd w' - let b:toc.prev_winid = l:prev_winid - endif -endfunction - -" }}}1 - -" -" Get the TOC entries -" -function! s:toc.get_entries(force) abort dict " {{{1 - if has_key(self, 'entries') && !self.refresh_always && !a:force - return self.entries - endif - - let self.entries = vimtex#parser#toc() - let self.topmatters = vimtex#parser#toc#get_topmatters() - - " - " Sort todo entries - " - if self.todo_sorted - let l:todos = filter(copy(self.entries), 'v:val.type ==# ''todo''') - for l:t in l:todos[1:] - let l:t.level = 1 - endfor - call filter(self.entries, 'v:val.type !=# ''todo''') - let self.entries = l:todos + self.entries - endif - - " - " Add hotkeys to entries - " - if self.hotkeys_enabled - let k = strwidth(self.hotkeys) - let n = len(self.entries) - let m = len(s:base(n, k)) - let i = 0 - for entry in self.entries - let keys = map(s:base(i, k), 'strcharpart(self.hotkeys, v:val, 1)') - let keys = repeat([self.hotkeys[0]], m - len(keys)) + keys - let i+=1 - let entry.num = i - let entry.hotkey = join(keys, '') - endfor - endif - - " - " Apply active layers - " - for entry in self.entries - let entry.active = self.layer_status[entry.type] - endfor - - " - " Refresh if wanted - " - if a:force && self.is_open() - call self.refresh() - endif - - return self.entries -endfunction - -" }}}1 -function! s:toc.get_visible_entries() abort dict " {{{1 - return filter(deepcopy(get(self, 'entries', [])), 'self.entry_is_visible(v:val)') -endfunction - -" }}}1 -function! s:toc.entry_is_visible(entry) abort " {{{1 - return get(a:entry, 'active', 1) && !get(a:entry, 'hidden') - \ && (a:entry.type !=# 'content' || a:entry.level <= self.tocdepth) -endfunction - -" }}}1 - -" -" Creating, refreshing and filling the buffer -" -function! s:toc.create() abort dict " {{{1 - let l:bufnr = bufnr('') - let l:winid = win_getid() - let l:vimtex = get(b:, 'vimtex', {}) - let l:vimtex_syntax = get(b:, 'vimtex_syntax', {}) - - if self.split_pos ==# 'full' - silent execute 'edit' escape(self.name, ' ') - else - if self.resize - silent exe 'set columns +=' . self.split_width - endif - silent execute - \ self.split_pos self.split_width - \ 'new' escape(self.name, ' ') - endif - - let self.prev_bufnr = l:bufnr - let self.prev_winid = l:winid - let b:toc = self - let b:vimtex = l:vimtex - let b:vimtex_syntax = l:vimtex_syntax - - setlocal bufhidden=wipe - setlocal buftype=nofile - setlocal concealcursor=nvic - setlocal conceallevel=2 - setlocal cursorline - setlocal nobuflisted - setlocal nolist - setlocal nospell - setlocal noswapfile - setlocal nowrap - setlocal tabstop=8 - - if self.hide_line_numbers - setlocal nonumber - setlocal norelativenumber - endif - - call self.refresh() - call self.set_syntax() - - if self.fold_enable - let self.foldexpr = function('s:foldexpr') - let self.foldtext = function('s:foldtext') - setlocal foldmethod=expr - setlocal foldexpr=b:toc.foldexpr(v:lnum) - setlocal foldtext=b:toc.foldtext() - let &l:foldlevel = get(self, 'fold_level', - \ (self.fold_level_start > 0 - \ ? self.fold_level_start - \ : self.tocdepth)) - endif - - nnoremap <silent><nowait><buffer><expr> gg b:toc.show_help ? 'gg}}j' : 'gg' - nnoremap <silent><nowait><buffer> <esc>OA k - nnoremap <silent><nowait><buffer> <esc>OB j - nnoremap <silent><nowait><buffer> <esc>OC k - nnoremap <silent><nowait><buffer> <esc>OD j - nnoremap <silent><nowait><buffer> q :call b:toc.close()<cr> - nnoremap <silent><nowait><buffer> <esc> :call b:toc.close()<cr> - nnoremap <silent><nowait><buffer> <space> :call b:toc.activate_current(0)<cr> - nnoremap <silent><nowait><buffer> <2-leftmouse> :call b:toc.activate_current(0)<cr> - nnoremap <silent><nowait><buffer> <cr> :call b:toc.activate_current(1)<cr> - nnoremap <buffer><nowait><silent> h :call b:toc.toggle_help()<cr> - nnoremap <buffer><nowait><silent> f :call b:toc.filter()<cr> - nnoremap <buffer><nowait><silent> F :call b:toc.clear_filter()<cr> - nnoremap <buffer><nowait><silent> s :call b:toc.toggle_numbers()<cr> - nnoremap <buffer><nowait><silent> t :call b:toc.toggle_sorted_todos()<cr> - nnoremap <buffer><nowait><silent> r :call b:toc.get_entries(1)<cr> - nnoremap <buffer><nowait><silent> - :call b:toc.decrease_depth()<cr> - nnoremap <buffer><nowait><silent> + :call b:toc.increase_depth()<cr> - - for [type, key] in items(self.layer_keys) - execute printf( - \ 'nnoremap <buffer><nowait><silent> %s' - \ . ' :call b:toc.toggle_type(''%s'')<cr>', - \ key, type) - endfor - - if self.hotkeys_enabled - for entry in self.entries - execute printf( - \ 'nnoremap <buffer><nowait><silent> %s%s' - \ . ' :call b:toc.activate_hotkey(''%s'')<cr>', - \ self.hotkeys_leader, entry.hotkey, entry.hotkey) - endfor - endif - - " Jump to closest index - call vimtex#pos#set_cursor(self.get_closest_index()) - - if exists('#User#VimtexEventTocCreated') - doautocmd <nomodeline> User VimtexEventTocCreated - endif -endfunction - -" }}}1 -function! s:toc.refresh() abort dict " {{{1 - let l:toc_winnr = bufwinnr(bufnr(self.name)) - let l:buf_winnr = bufwinnr(bufnr('')) - - if l:toc_winnr < 0 - return - elseif l:buf_winnr != l:toc_winnr - silent execute l:toc_winnr . 'wincmd w' - endif - - call self.position_save() - setlocal modifiable - silent %delete _ - - call self.print_help() - call self.print_entries() - - 0delete _ - setlocal nomodifiable - call self.position_restore() - - if l:buf_winnr != l:toc_winnr - silent execute l:buf_winnr . 'wincmd w' - endif -endfunction - -" }}}1 -function! s:toc.set_syntax() abort dict "{{{1 - syntax clear - - if self.show_help - execute 'syntax match VimtexTocHelp' - \ '/^\%<' . self.help_nlines . 'l.*/' - \ 'contains=VimtexTocHelpKey,VimtexTocHelpLayerOn,VimtexTocHelpLayerOff' - - syntax match VimtexTocHelpKey /<\S*>/ contained - syntax match VimtexTocHelpKey /^\s*[-+<>a-zA-Z\/]\+\ze\s/ contained - \ contains=VimtexTocHelpKeySeparator - syntax match VimtexTocHelpKey /^Layers:\s*\zs[-+<>a-zA-Z\/]\+/ contained - syntax match VimtexTocHelpKeySeparator /\// contained - - syntax match VimtexTocHelpLayerOn /\w\++/ contained - \ contains=VimtexTocHelpConceal - syntax match VimtexTocHelpLayerOff /(hidden)/ contained - syntax match VimtexTocHelpLayerOff /\w\+-/ contained - \ contains=VimtexTocHelpConceal - syntax match VimtexTocHelpConceal /[+-]/ contained conceal - - highlight link VimtexTocHelpKeySeparator VimtexTocHelp - endif - - syntax match VimtexTocNum /\v(([A-Z]+>|\d+)(\.\d+)*)?\s*/ contained - execute 'syntax match VimtexTocTodo' - \ '/\v\s\zs%(' - \ . toupper(join(keys(g:vimtex_toc_todo_labels), '|')) . '): /' - \ 'contained' - syntax match VimtexTocHotkey /\[[^]]\+\]/ contained - - syntax match VimtexTocSec0 /^L0.*/ contains=@VimtexTocStuff - syntax match VimtexTocSec1 /^L1.*/ contains=@VimtexTocStuff - syntax match VimtexTocSec2 /^L2.*/ contains=@VimtexTocStuff - syntax match VimtexTocSec3 /^L3.*/ contains=@VimtexTocStuff - syntax match VimtexTocSec4 /^L[4-9].*/ contains=@VimtexTocStuff - syntax match VimtexTocSecLabel /^L\d / contained conceal - \ nextgroup=VimtexTocNum - syntax cluster VimtexTocStuff - \ contains=VimtexTocSecLabel,VimtexTocHotkey,VimtexTocTodo,@Tex - - syntax match VimtexTocIncl /\v^L\d (\[i\])?\s*(\[\w+\] )?\w+ incl:/ - \ contains=VimtexTocSecLabel,VimtexTocHotkey - \ nextgroup=VimtexTocInclPath - syntax match VimtexTocInclPath /.*/ contained - - syntax match VimtexTocLabelsSecs /\v^L\d \s*(\[\w+\] )?(chap|sec):.*$/ - \ contains=VimtexTocSecLabel,VimtexTocHotkey - syntax match VimtexTocLabelsEq /\v^L\d \s*(\[\w+\] )?eq:.*$/ - \ contains=VimtexTocSecLabel,VimtexTocHotkey - syntax match VimtexTocLabelsFig /\v^L\d \s*(\[\w+\] )?fig:.*$/ - \ contains=VimtexTocSecLabel,VimtexTocHotkey - syntax match VimtexTocLabelsTab /\v^L\d \s*(\[\w+\] )?tab:.*$/ - \ contains=VimtexTocSecLabel,VimtexTocHotkey -endfunction - -" }}}1 - -" -" Print the TOC entries -" -function! s:toc.print_help() abort dict " {{{1 - let self.help_nlines = 0 - if !self.show_help | return | endif - - let help_text = [ - \ '<Esc>/q Close', - \ '<Space> Jump', - \ '<Enter> Jump and close', - \ ' r Refresh', - \ ' h Toggle help text', - \ ' t Toggle sorted TODOs', - \ ' -/+ Decrease/increase ToC depth (for content layer)', - \ ' f/F Apply/clear filter', - \] - - if self.layer_status.content - call add(help_text, ' s Hide numbering') - endif - call add(help_text, '') - - let l:first = 1 - let l:frmt = printf('%%-%ds', - \ max(map(values(self.layer_keys), 'strlen(v:val)')) + 2) - for [layer, status] in items(self.layer_status) - call add(help_text, - \ (l:first ? 'Layers: ' : ' ') - \ . printf(l:frmt, self.layer_keys[layer]) - \ . layer . (status ? '+' : '- (hidden)')) - let l:first = 0 - endfor - - call append('$', help_text) - call append('$', '') - - let self.help_nlines += len(help_text) + 1 -endfunction - -" }}}1 -function! s:toc.print_entries() abort dict " {{{1 - call self.set_number_format() - - for entry in self.get_visible_entries() - call self.print_entry(entry) - endfor -endfunction - -" }}}1 -function! s:toc.print_entry(entry) abort dict " {{{1 - let output = 'L' . a:entry.level . ' ' - if self.show_numbers - let number = a:entry.level >= self.tocdepth + 2 ? '' - \ : strpart(self.print_number(a:entry.number), - \ 0, self.number_width - 1) - let output .= printf(self.number_format, number) - endif - - if self.hotkeys_enabled - let output .= printf('[%S] ', a:entry.hotkey) - endif - - let output .= a:entry.title - - call append('$', output) -endfunction - -" }}}1 -function! s:toc.print_number(number) abort dict " {{{1 - if empty(a:number) | return '' | endif - if type(a:number) == type('') | return a:number | endif - - if get(a:number, 'part_toggle') - return s:int_to_roman(a:number.part) - endif - - let number = [ - \ a:number.chapter, - \ a:number.section, - \ a:number.subsection, - \ a:number.subsubsection, - \ a:number.subsubsubsection, - \ ] - - " Remove unused parts - while len(number) > 0 && number[0] == 0 - call remove(number, 0) - endwhile - while len(number) > 0 && number[-1] == 0 - call remove(number, -1) - endwhile - - " Change numbering in frontmatter, appendix, and backmatter - if self.topmatters > 1 - \ && (a:number.frontmatter || a:number.backmatter) - return '' - elseif a:number.appendix - let number[0] = nr2char(number[0] + 64) - endif - - return join(number, '.') -endfunction - -" }}}1 -function! s:toc.set_number_format() abort dict " {{{1 - let number_width = 0 - for entry in self.get_visible_entries() - let number_width = max([number_width, strlen(self.print_number(entry.number)) + 1]) - endfor - - let self.number_width = self.layer_status.content - \ ? max([0, min([2*(self.tocdepth + 2), number_width])]) - \ : 0 - let self.number_format = '%-' . self.number_width . 's' -endfunction - -" }}}1 - -" -" Interactions with TOC buffer/window -" -function! s:toc.activate_current(close_after) abort dict "{{{1 - let n = vimtex#pos#get_cursor_line() - 1 - if n < self.help_nlines | return {} | endif - - let l:count = 0 - for l:entry in self.get_visible_entries() - if l:count == n - self.help_nlines - return self.activate_entry(l:entry, a:close_after) - endif - let l:count += 1 - endfor - - return {} -endfunction - -" }}}1 -function! s:toc.activate_hotkey(key) abort dict "{{{1 - for entry in self.entries - if entry.hotkey ==# a:key - return self.activate_entry(entry, 1) - endif - endfor - - return {} -endfunction - -" }}}1 -function! s:toc.activate_entry(entry, close_after) abort dict "{{{1 - let self.prev_index = vimtex#pos#get_cursor_line() - let l:vimtex_main = get(b:vimtex, 'tex', '') - - " Save toc winnr info for later use - let toc_winnr = winnr() - - " Return to calling window - call win_gotoid(self.prev_winid) - - " Get buffer number, add buffer if necessary - let bnr = bufnr(a:entry.file) - if bnr == -1 - execute 'badd ' . fnameescape(a:entry.file) - let bnr = bufnr(a:entry.file) - endif - - " Set bufferopen command - " The point here is to use existing open buffer if the user has turned on - " the &switchbuf option to either 'useopen' or 'usetab' - let cmd = 'buffer! ' - if &switchbuf =~# 'usetab' - for i in range(tabpagenr('$')) - if index(tabpagebuflist(i + 1), bnr) >= 0 - let cmd = 'sbuffer! ' - break - endif - endfor - elseif &switchbuf =~# 'useopen' - if bufwinnr(bnr) > 0 - let cmd = 'sbuffer! ' - endif - endif - - " Open file buffer - execute 'keepalt' cmd bnr - - " Go to entry line - if has_key(a:entry, 'line') - call vimtex#pos#set_cursor(a:entry.line, 0) - endif - - " If relevant, enable vimtex stuff - if get(a:entry, 'link', 0) && !empty(l:vimtex_main) - let b:vimtex_main = l:vimtex_main - call vimtex#init() - endif - - " Ensure folds are opened - normal! zv - - " Keep or close toc window (based on options) - if a:close_after && self.split_pos !=# 'full' - call self.close() - else - " Return to toc window - execute toc_winnr . 'wincmd w' - endif - - " Allow user entry points through autocmd events - if exists('#User#VimtexEventTocActivated') - doautocmd <nomodeline> User VimtexEventTocActivated - endif -endfunction - -" }}}1 -function! s:toc.toggle_help() abort dict "{{{1 - let l:pos = vimtex#pos#get_cursor() - if self.show_help - let l:pos[1] -= self.help_nlines - call vimtex#pos#set_cursor(l:pos) - endif - - let self.show_help = self.show_help ? 0 : 1 - call self.refresh() - call self.set_syntax() - - if self.show_help - let l:pos[1] += self.help_nlines - call vimtex#pos#set_cursor(l:pos) - endif -endfunction - -" }}}1 -function! s:toc.toggle_numbers() abort dict "{{{1 - let self.show_numbers = self.show_numbers ? 0 : 1 - call self.refresh() -endfunction - -" }}}1 -function! s:toc.toggle_sorted_todos() abort dict "{{{1 - let self.todo_sorted = self.todo_sorted ? 0 : 1 - call self.get_entries(1) - call vimtex#pos#set_cursor(self.get_closest_index()) -endfunction - -" }}}1 -function! s:toc.toggle_type(type) abort dict "{{{1 - let self.layer_status[a:type] = !self.layer_status[a:type] - for entry in self.entries - if entry.type ==# a:type - let entry.active = self.layer_status[a:type] - endif - endfor - call self.refresh() -endfunction - -" }}}1 -function! s:toc.decrease_depth() abort dict "{{{1 - let self.tocdepth = max([self.tocdepth - 1, -2]) - call self.refresh() -endfunction - -" }}}1 -function! s:toc.increase_depth() abort dict "{{{1 - let self.tocdepth = min([self.tocdepth + 1, 5]) - call self.refresh() -endfunction - -" }}}1 -function! s:toc.filter() dict abort "{{{1 - let re_filter = input('filter entry title by: ') - for entry in self.entries - let entry.hidden = get(entry, 'hidden') || entry.title !~# re_filter - endfor - call self.refresh() -endfunction - -" }}}1 -function! s:toc.clear_filter() dict abort "{{{1 - for entry in self.entries - let entry.hidden = 0 - endfor - call self.refresh() -endfunction - -" }}}1 - -" -" Utility functions -" -function! s:toc.get_closest_index() abort dict " {{{1 - let l:calling_rank = 0 - let l:not_found = 1 - for [l:file, l:lnum, l:line] in vimtex#parser#tex(b:vimtex.tex) - let l:calling_rank += 1 - if l:file ==# self.calling_file && l:lnum >= self.calling_line - let l:not_found = 0 - break - endif - endfor - - if l:not_found - return [0, get(self, 'prev_index', self.help_nlines + 1), 0, 0] - endif - - let l:index = 0 - let l:dist = 0 - let l:closest_index = 1 - let l:closest_dist = 10000 - for l:entry in self.get_visible_entries() - let l:index += 1 - let l:dist = l:calling_rank - entry.rank - - if l:dist >= 0 && l:dist < l:closest_dist - let l:closest_dist = l:dist - let l:closest_index = l:index - endif - endfor - - return [0, l:closest_index + self.help_nlines, 0, 0] -endfunction - -" }}}1 -function! s:toc.position_save() abort dict " {{{1 - let self.position = vimtex#pos#get_cursor() -endfunction - -" }}}1 -function! s:toc.position_restore() abort dict " {{{1 - if self.position[1] <= self.help_nlines - let self.position[1] = self.help_nlines + 1 - endif - call vimtex#pos#set_cursor(self.position) -endfunction - -" }}}1 - - -function! s:foldexpr(lnum) abort " {{{1 - let pline = getline(a:lnum - 1) - let cline = getline(a:lnum) - let nline = getline(a:lnum + 1) - let l:pn = matchstr(pline, '^L\zs\d') - let l:cn = matchstr(cline, '^L\zs\d') - let l:nn = matchstr(nline, '^L\zs\d') - - " Don't fold options - if cline =~# '^\s*$' - return 0 - endif - - if l:nn > l:cn - return '>' . l:nn - endif - - if l:cn < l:pn - return l:cn - endif - - return '=' -endfunction - -" }}}1 -function! s:foldtext() abort " {{{1 - let l:line = getline(v:foldstart)[3:] - if b:toc.todo_sorted - \ && l:line =~# '\v%(' . join(keys(g:vimtex_toc_todo_labels), '|') . ')' - return substitute(l:line, '\w+\zs:.*', 's', '') - else - return l:line - endif -endfunction - -" }}}1 - -function! s:int_to_roman(number) abort " {{{1 - let l:number = a:number - let l:result = '' - for [l:val, l:romn] in [ - \ ['1000', 'M'], - \ ['900', 'CM'], - \ ['500', 'D'], - \ ['400', 'CD' ], - \ ['100', 'C'], - \ ['90', 'XC'], - \ ['50', 'L'], - \ ['40', 'XL'], - \ ['10', 'X'], - \ ['9', 'IX'], - \ ['5', 'V'], - \ ['4', 'IV'], - \ ['1', 'I'], - \] - while l:number >= l:val - let l:number -= l:val - let l:result .= l:romn - endwhile - endfor - - return l:result -endfunction - -" }}}1 -function! s:base(n, k) abort " {{{1 - if a:n < a:k - return [a:n] - else - return add(s:base(a:n/a:k, a:k), a:n % a:k) - endif -endfunction - -" }}}1 - -endif |