Implemented a new system for displaying ToCs
This commit is contained in:
parent
e12e73a3a0
commit
bd1de1feef
@ -15,6 +15,7 @@ function! vimtex#init() " {{{1
|
||||
call vimtex#echo#init(s:initialized)
|
||||
call vimtex#fold#init(s:initialized)
|
||||
call vimtex#view#init(s:initialized)
|
||||
call vimtex#index#init(s:initialized)
|
||||
call vimtex#motion#init(s:initialized)
|
||||
call vimtex#labels#init(s:initialized)
|
||||
call vimtex#change#init(s:initialized)
|
||||
|
207
autoload/vimtex/index.vim
Normal file
207
autoload/vimtex/index.vim
Normal file
@ -0,0 +1,207 @@
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex#index#init(initialized) " {{{1
|
||||
call vimtex#util#set_default('g:vimtex_index_hide_line_numbers', 1)
|
||||
call vimtex#util#set_default('g:vimtex_index_show_help', 1)
|
||||
call vimtex#util#set_default('g:vimtex_index_resize', 0)
|
||||
call vimtex#util#set_default('g:vimtex_index_split', 'vert leftabove 30')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#index#open(bufname) " {{{1
|
||||
let winnr = bufwinnr(bufnr(a:bufname))
|
||||
if winnr >= 0
|
||||
silent execute winnr . 'wincmd w'
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#index#close(bufname) " {{{1
|
||||
if g:vimtex_index_resize
|
||||
silent exe 'set columns -=' . g:vimtex_toc_width
|
||||
endif
|
||||
silent execute 'bwipeout' . bufnr(a:bufname)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex#index#create(index) " {{{1
|
||||
let default = {
|
||||
\ 'refresh' : function('s:actions_refresh'),
|
||||
\ 'activate' : function('s:actions_activate'),
|
||||
\ 'close' : function('s:actions_close'),
|
||||
\ 'print_entries' : function('s:print_entries'),
|
||||
\ 'print_help' : function('s:print_help'),
|
||||
\ 'syntax' : function('s:syntax'),
|
||||
\ 'show_help' : g:vimtex_index_show_help,
|
||||
\ }
|
||||
for [key, FnVal] in items(default)
|
||||
if !has_key(a:index, key)
|
||||
let a:index[key] = FnVal
|
||||
endif
|
||||
unlet FnVal
|
||||
endfor
|
||||
|
||||
if g:vimtex_index_resize
|
||||
silent exe 'set columns +=' . g:vimtex_index_width
|
||||
endif
|
||||
silent execute g:vimtex_index_split 'new' escape(a:index.name, ' ')
|
||||
let b:index = a:index
|
||||
|
||||
setlocal bufhidden=wipe
|
||||
setlocal buftype=nofile
|
||||
setlocal concealcursor=nvic
|
||||
setlocal conceallevel=0
|
||||
setlocal cursorline
|
||||
setlocal listchars=
|
||||
setlocal nobuflisted
|
||||
setlocal nolist
|
||||
setlocal nospell
|
||||
setlocal noswapfile
|
||||
setlocal nowrap
|
||||
setlocal tabstop=8
|
||||
|
||||
if g:vimtex_index_hide_line_numbers
|
||||
setlocal nonumber
|
||||
setlocal norelativenumber
|
||||
endif
|
||||
|
||||
nnoremap <silent><buffer> G G{k
|
||||
nnoremap <silent><buffer> <esc>OA k
|
||||
nnoremap <silent><buffer> <esc>OB j
|
||||
nnoremap <silent><buffer> <esc>OC k
|
||||
nnoremap <silent><buffer> <esc>OD j
|
||||
nnoremap <silent><buffer> q :call b:index.close()<cr>
|
||||
nnoremap <silent><buffer> <esc> :call b:index.close()<cr>
|
||||
nnoremap <silent><buffer> <space> :call b:index.activate(0)<cr>
|
||||
nnoremap <silent><buffer> <leftrelease> :call b:index.activate(0)<cr>
|
||||
nnoremap <silent><buffer> <cr> :call b:index.activate(1)<cr>
|
||||
nnoremap <silent><buffer> <2-leftmouse> :call b:index.activate(1)<cr>
|
||||
|
||||
call b:index.syntax()
|
||||
call b:index.refresh()
|
||||
|
||||
if has_key(b:index, 'hook_init_post')
|
||||
call b:index.hook_init_post()
|
||||
unlet b:index.hook_init_post
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:actions_refresh() dict " {{{1
|
||||
let pos_saved = getpos('.')
|
||||
setlocal modifiable
|
||||
%delete
|
||||
|
||||
call self.print_entries()
|
||||
call self.print_help()
|
||||
|
||||
0delete _
|
||||
setlocal nomodifiable
|
||||
call setpos('.', pos_saved)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:actions_activate(close) dict "{{{1
|
||||
let n = getpos('.')[1] - 1
|
||||
if n >= len(self.entries)
|
||||
return
|
||||
endif
|
||||
let entry = self.entries[n]
|
||||
|
||||
" Save index buffer info for later use
|
||||
let toc_bnr = bufnr('%')
|
||||
let toc_wnr = winnr()
|
||||
|
||||
" Return to calling window
|
||||
wincmd w
|
||||
|
||||
" Get buffer number, add buffer if necessary
|
||||
let bnr = bufnr(entry.file)
|
||||
if bnr == -1
|
||||
execute 'badd ' . fnameescape(entry.file)
|
||||
let bnr = bufnr(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 cmd bnr
|
||||
|
||||
" Go to entry line
|
||||
call setpos('.', [0, entry.line, 0, 0])
|
||||
|
||||
" Ensure folds are opened
|
||||
normal! zv
|
||||
|
||||
" Keep or close index window (based on options)
|
||||
if a:close
|
||||
if g:vimtex_index_resize
|
||||
silent exe 'set columns -=' . g:vimtex_index_width
|
||||
endif
|
||||
execute 'bwipeout ' . toc_bnr
|
||||
else
|
||||
execute toc_wnr . 'wincmd w'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:actions_close() dict "{{{1
|
||||
if g:vimtex_index_resize
|
||||
silent exe 'set columns -=' . g:vimtex_index_width
|
||||
endif
|
||||
bwipeout
|
||||
endfunction
|
||||
|
||||
function! s:print_entries() dict " {{{1
|
||||
for entry in self.entries
|
||||
call append('$', printf(' %s', entry.title))
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:print_help() dict " {{{1
|
||||
if self.show_help
|
||||
call append('$', '')
|
||||
call append('$', '<Esc>/q: close')
|
||||
call append('$', '<Space>: jump')
|
||||
call append('$', '<Enter>: jump and close')
|
||||
if has_key(self, 'hook_print_help')
|
||||
call self.hook_print_help()
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:syntax() dict " {{{1
|
||||
syntax match IndexLine /^.*$/ contains=@Tex
|
||||
syntax match IndexHelp /^.*: .*/
|
||||
|
||||
highlight link IndexLine ModeMsg
|
||||
highlight link IndexHelp helpVim
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" vim: fdm=marker sw=2
|
@ -11,16 +11,13 @@ function! vimtex#toc#init(initialized) " {{{1
|
||||
" Set default options
|
||||
call vimtex#util#set_default('g:vimtex_toc_fold', 0)
|
||||
call vimtex#util#set_default('g:vimtex_toc_fold_levels', 10)
|
||||
call vimtex#util#set_default('g:vimtex_toc_hide_help', 0)
|
||||
call vimtex#util#set_default('g:vimtex_toc_hide_line_numbers', 1)
|
||||
call vimtex#util#set_default('g:vimtex_toc_hide_preamble', 0)
|
||||
call vimtex#util#set_default('g:vimtex_toc_numbers', 1)
|
||||
call vimtex#util#set_default('g:vimtex_toc_numbers_width', 0)
|
||||
call vimtex#util#set_default('g:vimtex_toc_resize', 1)
|
||||
call vimtex#util#set_default('g:vimtex_toc_show_preamble', 1)
|
||||
call vimtex#util#set_default('g:vimtex_toc_show_numbers', 1)
|
||||
call vimtex#util#set_default('g:vimtex_toc_number_width', 0)
|
||||
call vimtex#util#set_default('g:vimtex_toc_secnumdepth', 3)
|
||||
call vimtex#util#set_default('g:vimtex_toc_split_pos', 'vert leftabove')
|
||||
call vimtex#util#set_default('g:vimtex_toc_width', 30)
|
||||
call vimtex#util#error_deprecated('g:vimtex_toc_split_side')
|
||||
|
||||
" Set some constants
|
||||
let s:name = 'Table of contents (vimtex)'
|
||||
|
||||
" Define commands
|
||||
command! -buffer VimtexTocOpen call vimtex#toc#open()
|
||||
@ -32,44 +29,34 @@ function! vimtex#toc#init(initialized) " {{{1
|
||||
endfunction
|
||||
|
||||
function! vimtex#toc#open() " {{{1
|
||||
" Go to TOC if it already exists
|
||||
let winnr = bufwinnr(bufnr('LaTeX TOC'))
|
||||
if winnr >= 0
|
||||
silent execute winnr . 'wincmd w'
|
||||
return
|
||||
endif
|
||||
if vimtex#index#open(s:name) | return | endif
|
||||
|
||||
" Store tex buffer number and position and parse TOC data
|
||||
let calling_buf = bufnr('%')
|
||||
let calling_file = expand('%:p')
|
||||
let calling_line = line('.')
|
||||
let toc = s:parse_toc()
|
||||
let index = {
|
||||
\ 'name' : s:name,
|
||||
\ 'calling_file' : expand('%:p'),
|
||||
\ 'calling_line' : line('.'),
|
||||
\ 'entries' : s:parse_toc(),
|
||||
\ 'show_numbers' : g:vimtex_toc_show_numbers,
|
||||
\ 'max_level' : s:max_level,
|
||||
\ 'topmatters' : s:count_matters,
|
||||
\ 'secnumdepth' : g:vimtex_toc_secnumdepth,
|
||||
\ 'hook_init_post' : function('s:index_hook_init_post'),
|
||||
\ 'hook_print_help' : function('s:index_hook_print_help'),
|
||||
\ 'print_entries' : function('s:index_print_entries'),
|
||||
\ 'print_entry' : function('s:index_print_entry'),
|
||||
\ 'print_number' : function('s:index_print_number'),
|
||||
\ 'increase_depth' : function('s:index_secnumdepth_increase'),
|
||||
\ 'decrease_depth' : function('s:index_secnumdepth_decrease'),
|
||||
\ 'syntax' : function('s:index_syntax'),
|
||||
\ 'toggle_numbers' : function('s:index_toggle_numbers'),
|
||||
\ }
|
||||
|
||||
" Resize vim session if wanted, then create TOC window
|
||||
if g:vimtex_toc_resize
|
||||
silent exe "set columns+=" . g:vimtex_toc_width
|
||||
endif
|
||||
silent exe g:vimtex_toc_split_pos g:vimtex_toc_width . 'new LaTeX\ TOC'
|
||||
|
||||
" Set buffer local variables
|
||||
let b:toc = toc
|
||||
let b:toc_numbers = 1
|
||||
let b:toc_max_level = s:max_level
|
||||
let b:toc_topmatters = s:count_matters
|
||||
let b:toc_secnumdepth = g:vimtex_toc_secnumdepth
|
||||
let b:calling_winnr = bufwinnr(calling_buf)
|
||||
let b:calling_file = calling_file
|
||||
let b:calling_line = calling_line
|
||||
|
||||
setlocal filetype=vimtex_toc
|
||||
call vimtex#index#create(index)
|
||||
endfunction
|
||||
|
||||
function! vimtex#toc#toggle() " {{{1
|
||||
if bufwinnr(bufnr('LaTeX TOC')) >= 0
|
||||
if g:vimtex_toc_resize
|
||||
silent exe "set columns-=" . g:vimtex_toc_width
|
||||
endif
|
||||
silent execute 'bwipeout' . bufnr('LaTeX TOC')
|
||||
if vimtex#index#open(s:name)
|
||||
call vimtex#index#close(s:name)
|
||||
else
|
||||
call vimtex#toc#open()
|
||||
silent execute 'wincmd w'
|
||||
@ -78,6 +65,169 @@ endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:index_fold_level(lnum) " {{{1
|
||||
let pline = getline(a:lnum - 1)
|
||||
let cline = getline(a:lnum)
|
||||
let nline = getline(a:lnum + 1)
|
||||
let l:pn = matchstr(pline, '\d$')
|
||||
let l:cn = matchstr(cline, '\d$')
|
||||
let l:nn = matchstr(nline, '\d$')
|
||||
|
||||
" Don't fold options
|
||||
if cline =~# '^\s*$'
|
||||
return 0
|
||||
endif
|
||||
|
||||
if l:nn > l:cn && g:vimtex_toc_fold_levels >= l:nn
|
||||
return '>' . l:nn
|
||||
endif
|
||||
|
||||
if l:cn < l:pn && l:cn >= l:nn && g:vimtex_toc_fold_levels >= l:cn
|
||||
return l:cn
|
||||
endif
|
||||
|
||||
return '='
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_fold_text() " {{{1
|
||||
return getline(v:foldstart)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_hook_init_post() dict " {{{1
|
||||
if g:vimtex_toc_fold
|
||||
let self.fold_level = function('s:index_fold_level')
|
||||
let self.fold_text = function('s:index_fold_text')
|
||||
setlocal foldmethod=expr
|
||||
setlocal foldexpr=b:index.fold_level(v:lnum)
|
||||
setlocal foldtext=b:index.fold_text()
|
||||
endif
|
||||
|
||||
nnoremap <buffer> <silent> s :call b:index.toggle_numbers()<cr>
|
||||
nnoremap <buffer> <silent> - :call b:index.decrease_depth()<cr>
|
||||
nnoremap <buffer> <silent> + :call b:index.increase_depth()<cr>
|
||||
|
||||
" Jump to closest index
|
||||
call setpos('.', self.pos_closest)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_hook_print_help() dict " {{{1
|
||||
call append('$', '-: decrease secnumpdeth')
|
||||
call append('$', '+: increase secnumpdeth')
|
||||
call append('$', 's: hide numbering')
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_print_entries() dict " {{{1
|
||||
if g:vimtex_toc_number_width
|
||||
let self.number_width = g:vimtex_toc_number_width
|
||||
else
|
||||
let self.number_width = 2*(self.secnumdepth + 2)
|
||||
endif
|
||||
let self.number_width = max([0, self.number_width])
|
||||
let self.number_format = '%-' . self.number_width . 's'
|
||||
|
||||
let index = 0
|
||||
let closest_index = 0
|
||||
for entry in self.entries
|
||||
let index += 1
|
||||
call self.print_entry(entry)
|
||||
if entry.file == self.calling_file && entry.line <= self.calling_line
|
||||
let closest_index = index
|
||||
endif
|
||||
endfor
|
||||
|
||||
let self.pos_closest = [0, closest_index, 0, 0]
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_print_entry(entry) dict " {{{1
|
||||
let level = self.max_level - a:entry.level
|
||||
|
||||
let output = ''
|
||||
if self.show_numbers
|
||||
let number = level >= self.secnumdepth + 2 ? ''
|
||||
\ : strpart(self.print_number(a:entry.number), 0, self.number_width - 1)
|
||||
let output .= printf(self.number_format, number)
|
||||
endif
|
||||
let output .= printf('%-140S%s', a:entry.title, level)
|
||||
|
||||
call append('$', output)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_print_number(number) dict " {{{1
|
||||
if empty(a:number) | return '' | endif
|
||||
|
||||
let number = [
|
||||
\ a:number.part,
|
||||
\ a:number.chapter,
|
||||
\ a:number.section,
|
||||
\ a:number.subsection,
|
||||
\ a:number.subsubsection,
|
||||
\ a:number.subsubsubsection,
|
||||
\ ]
|
||||
|
||||
" Remove unused parts
|
||||
while number[0] == 0
|
||||
call remove(number, 0)
|
||||
endwhile
|
||||
while 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:index_secnumdepth_decrease() dict "{{{1
|
||||
let self.secnumdepth = max([self.secnumdepth - 1, -2])
|
||||
call self.refresh()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_secnumdepth_increase() dict "{{{1
|
||||
let self.secnumdepth = min([self.secnumdepth + 1, 5])
|
||||
call self.refresh()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_syntax() dict "{{{1
|
||||
syntax match TocNum /^\(\([A-Z]\+\>\|\d\+\)\(\.\d\+\)*\)\?\s*/ contained
|
||||
syntax match TocSec0 /^.*0$/ contains=TocNum,@Tex
|
||||
syntax match TocSec1 /^.*1$/ contains=TocNum,@Tex
|
||||
syntax match TocSec2 /^.*2$/ contains=TocNum,@Tex
|
||||
syntax match TocSec3 /^.*3$/ contains=TocNum,@Tex
|
||||
syntax match TocSec4 /^.*4$/ contains=TocNum,@Tex
|
||||
syntax match TocHelp /^.*: .*/
|
||||
|
||||
highlight link TocNum Number
|
||||
highlight link TocSec0 Title
|
||||
highlight link TocSec1 Normal
|
||||
highlight link TocSec2 helpVim
|
||||
highlight link TocSec3 NonText
|
||||
highlight link TocSec4 Comment
|
||||
highlight link TocHelp helpVim
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:index_toggle_numbers() dict "{{{1
|
||||
let self.show_numbers = self.show_numbers ? 0 : 1
|
||||
call self.refresh()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" {{{1 TOC variables
|
||||
let s:max_level = 0
|
||||
let s:count_matters = 0
|
||||
@ -157,8 +307,8 @@ endfunction
|
||||
" }}}1
|
||||
function! s:parse_limits(file) " {{{1
|
||||
if !filereadable(a:file)
|
||||
echoerr "Error in vimtex#toc s:parse_limits"
|
||||
echoerr "File not readable: " . a:file
|
||||
echoerr 'Error in vimtex#toc s:parse_limits'
|
||||
echoerr 'File not readable: ' . a:file
|
||||
return ''
|
||||
endif
|
||||
|
||||
@ -188,11 +338,11 @@ function! s:parse_file(file) " {{{1
|
||||
" level : 2,
|
||||
" }
|
||||
|
||||
if a:file == ''
|
||||
if a:file ==# ''
|
||||
return []
|
||||
elseif !filereadable(a:file)
|
||||
echoerr "Error in vimtex#toc s:parse_file"
|
||||
echoerr "File not readable: " . a:file
|
||||
echoerr 'Error in vimtex#toc s:parse_file'
|
||||
echoerr 'File not readable: ' . a:file
|
||||
return []
|
||||
endif
|
||||
|
||||
@ -210,7 +360,7 @@ function! s:parse_file(file) " {{{1
|
||||
|
||||
" 2. Parse preamble
|
||||
if s:number.preamble
|
||||
if !g:vimtex_toc_hide_preamble && line =~# '\v^\s*\\documentclass'
|
||||
if g:vimtex_toc_show_preamble && line =~# '\v^\s*\\documentclass'
|
||||
call add(toc, {
|
||||
\ 'title' : 'Preamble',
|
||||
\ 'number' : '',
|
||||
@ -314,32 +464,32 @@ endfunction
|
||||
|
||||
function! s:number_increment(level) " {{{1
|
||||
" Increment numbers
|
||||
if a:level == 'part'
|
||||
if a:level ==# 'part'
|
||||
let s:number.part += 1
|
||||
let s:number.chapter = 0
|
||||
let s:number.section = 0
|
||||
let s:number.subsection = 0
|
||||
let s:number.subsubsection = 0
|
||||
let s:number.subsubsubsection = 0
|
||||
elseif a:level == 'chapter'
|
||||
elseif a:level ==# 'chapter'
|
||||
let s:number.chapter += 1
|
||||
let s:number.section = 0
|
||||
let s:number.subsection = 0
|
||||
let s:number.subsubsection = 0
|
||||
let s:number.subsubsubsection = 0
|
||||
elseif a:level == 'section'
|
||||
elseif a:level ==# 'section'
|
||||
let s:number.section += 1
|
||||
let s:number.subsection = 0
|
||||
let s:number.subsubsection = 0
|
||||
let s:number.subsubsubsection = 0
|
||||
elseif a:level == 'subsection'
|
||||
elseif a:level ==# 'subsection'
|
||||
let s:number.subsection += 1
|
||||
let s:number.subsubsection = 0
|
||||
let s:number.subsubsubsection = 0
|
||||
elseif a:level == 'subsubsection'
|
||||
elseif a:level ==# 'subsubsection'
|
||||
let s:number.subsubsection += 1
|
||||
let s:number.subsubsubsection = 0
|
||||
elseif a:level == 'subsubsubsection'
|
||||
elseif a:level ==# 'subsubsubsection'
|
||||
let s:number.subsubsubsection += 1
|
||||
endif
|
||||
|
||||
|
@ -1,161 +0,0 @@
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
function! vimtex_toc#init() " {{{1
|
||||
if !exists('b:toc') | return | endif
|
||||
|
||||
" Fill TOC entries
|
||||
call s:add_start()
|
||||
call s:add_entries()
|
||||
call s:add_help()
|
||||
call s:add_end()
|
||||
|
||||
" Jump to closest index
|
||||
call setpos('.', b:toc_pos_closest)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex_toc#fold_level(lnum) " {{{1
|
||||
let pline = getline(a:lnum - 1)
|
||||
let cline = getline(a:lnum)
|
||||
let nline = getline(a:lnum + 1)
|
||||
let l:pn = matchstr(pline, '\d$')
|
||||
let l:cn = matchstr(cline, '\d$')
|
||||
let l:nn = matchstr(nline, '\d$')
|
||||
|
||||
" Don't fold options
|
||||
if cline =~# '^\s*$'
|
||||
return 0
|
||||
endif
|
||||
|
||||
if l:nn > l:cn && g:vimtex_toc_fold_levels >= l:nn
|
||||
return '>' . l:nn
|
||||
endif
|
||||
|
||||
if l:cn < l:pn && l:cn >= l:nn && g:vimtex_toc_fold_levels >= l:cn
|
||||
return l:cn
|
||||
endif
|
||||
|
||||
return '='
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex_toc#fold_text() " {{{1
|
||||
return getline(v:foldstart)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! vimtex_toc#refresh() " {{{1
|
||||
if !exists('b:toc') | return | endif
|
||||
|
||||
" Fill TOC entries
|
||||
call s:add_start()
|
||||
call s:add_entries()
|
||||
call s:add_help()
|
||||
call s:add_end()
|
||||
|
||||
" Restore old position
|
||||
call setpos('.', b:toc_pos_saved)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:add_start() " {{{1
|
||||
let b:toc_pos_saved = getpos('.')
|
||||
setlocal modifiable
|
||||
%delete
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:add_entries() " {{{1
|
||||
let closest_index = 0
|
||||
if g:vimtex_toc_numbers_width
|
||||
let s:width = g:vimtex_toc_numbers_width
|
||||
else
|
||||
let s:width = 2*(b:toc_secnumdepth+2)
|
||||
endi
|
||||
let s:width = max([0, s:width])
|
||||
let s:num_format = '%-' . s:width . 's'
|
||||
|
||||
let index = 0
|
||||
for entry in b:toc
|
||||
let index += 1
|
||||
call s:print_entry(entry)
|
||||
if entry.file == b:calling_file && entry.line <= b:calling_line
|
||||
let closest_index = index
|
||||
endif
|
||||
endfor
|
||||
|
||||
let b:toc_pos_closest = [0, closest_index, 0, 0]
|
||||
endfunction
|
||||
" }}}1
|
||||
function! s:add_help() " {{{1
|
||||
if !g:vimtex_toc_hide_help
|
||||
call append('$', "")
|
||||
call append('$', "<Esc>/q: close")
|
||||
call append('$', "<Space>: jump")
|
||||
call append('$', "<Enter>: jump and close")
|
||||
call append('$', "-: decrease secnumpdeth")
|
||||
call append('$', "+: increase secnumpdeth")
|
||||
call append('$', "s: hide numbering")
|
||||
endif
|
||||
endfunction
|
||||
" }}}1
|
||||
function! s:add_end() " {{{1
|
||||
0delete _
|
||||
setlocal nomodifiable
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:print_entry(entry) " {{{1
|
||||
let level = b:toc_max_level - a:entry.level
|
||||
|
||||
" Create entry string
|
||||
let entry = ''
|
||||
if g:vimtex_toc_numbers
|
||||
let entry .= printf(s:num_format, level >= b:toc_secnumdepth + 2
|
||||
\ ? '' : strpart(s:print_number(a:entry.number), 0, s:width))
|
||||
endif
|
||||
let entry .= printf('%-140S%s', a:entry.title, level)
|
||||
|
||||
call append('$', entry)
|
||||
endfunction
|
||||
" }}}1
|
||||
function! s:print_number(number) " {{{1
|
||||
if empty(a:number) | return "" | endif
|
||||
|
||||
let number = [
|
||||
\ a:number.part,
|
||||
\ a:number.chapter,
|
||||
\ a:number.section,
|
||||
\ a:number.subsection,
|
||||
\ a:number.subsubsection,
|
||||
\ a:number.subsubsubsection,
|
||||
\ ]
|
||||
|
||||
" Remove unused parts
|
||||
while number[0] == 0
|
||||
call remove(number, 0)
|
||||
endwhile
|
||||
while number[-1] == 0
|
||||
call remove(number, -1)
|
||||
endwhile
|
||||
|
||||
" Change numbering in frontmatter, appendix, and backmatter
|
||||
if b:toc_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
|
||||
|
||||
" vim: fdm=marker sw=2
|
@ -1,155 +0,0 @@
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
if exists('b:did_ftplugin')
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
" Set local buffer settings
|
||||
setlocal buftype=nofile
|
||||
setlocal bufhidden=wipe
|
||||
setlocal listchars=
|
||||
setlocal nobuflisted
|
||||
setlocal noswapfile
|
||||
setlocal nowrap
|
||||
if g:vimtex_toc_hide_line_numbers
|
||||
setlocal nonumber
|
||||
setlocal norelativenumber
|
||||
endif
|
||||
setlocal nolist
|
||||
setlocal nospell
|
||||
setlocal cursorline
|
||||
setlocal tabstop=8
|
||||
setlocal cole=0
|
||||
setlocal cocu=nvic
|
||||
if g:vimtex_toc_fold
|
||||
setlocal foldmethod=expr
|
||||
setlocal foldexpr=vimtex_toc#fold_level(v:lnum)
|
||||
setlocal foldtext=vimtex_toc#fold_text()
|
||||
endif
|
||||
|
||||
" Refresh/Initialize TOC content
|
||||
call vimtex_toc#init()
|
||||
|
||||
" Define mappings
|
||||
nnoremap <buffer> <silent> G G4k
|
||||
nnoremap <buffer> <silent> <Esc>OA k
|
||||
nnoremap <buffer> <silent> <Esc>OB j
|
||||
nnoremap <buffer> <silent> <Esc>OC l
|
||||
nnoremap <buffer> <silent> <Esc>OD h
|
||||
nnoremap <buffer> <silent> s :call <SID>toc_toggle_numbers()<cr>
|
||||
nnoremap <buffer> <silent> - :call <SID>toc_dec_secnumdepth()<cr>
|
||||
nnoremap <buffer> <silent> + :call <SID>toc_inc_secnumdepth()<cr>
|
||||
nnoremap <buffer> <silent> q :call <SID>toc_close()<cr>
|
||||
nnoremap <buffer> <silent> <Esc> :call <SID>toc_close()<cr>
|
||||
nnoremap <buffer> <silent> <Space> :call <SID>toc_activate(0)<cr>
|
||||
nnoremap <buffer> <silent> <leftrelease> :call <SID>toc_activate(0)<cr>
|
||||
nnoremap <buffer> <silent> <CR> :call <SID>toc_activate(1)<cr>
|
||||
nnoremap <buffer> <silent> <2-leftmouse> :call <SID>toc_activate(1)<cr>
|
||||
|
||||
function! s:toc_activate(close) "{{{1
|
||||
" Get TOC entry, do nothing if no entry found
|
||||
" entry = {
|
||||
" title : ...,
|
||||
" number : ...,
|
||||
" file : ...,
|
||||
" line : ...,
|
||||
" }
|
||||
let n = getpos('.')[1] - 1
|
||||
if n >= len(b:toc)
|
||||
return
|
||||
endif
|
||||
let entry = b:toc[n]
|
||||
|
||||
" Save TOC buffer info for later use
|
||||
let toc_bnr = bufnr('%')
|
||||
let toc_wnr = winnr()
|
||||
|
||||
" Return to calling window
|
||||
execute b:calling_winnr . 'wincmd w'
|
||||
|
||||
" Open file and line for given TOC entry
|
||||
call s:toc_open_entry(entry)
|
||||
|
||||
" Keep or close TOC window (based on options)
|
||||
if a:close
|
||||
if g:vimtex_toc_resize
|
||||
silent exe "set columns-=" . g:vimtex_toc_width
|
||||
endif
|
||||
execute 'bwipeout ' . toc_bnr
|
||||
else
|
||||
execute toc_wnr . 'wincmd w'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:toc_close() "{{{1
|
||||
if g:vimtex_toc_resize
|
||||
silent exe "set columns-=" . g:vimtex_toc_width
|
||||
endif
|
||||
bwipeout
|
||||
endfunction
|
||||
|
||||
function! s:toc_open_entry(entry) "{{{1
|
||||
" 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 cmd . bnr
|
||||
|
||||
" Go to entry line
|
||||
call setpos('.', [0, a:entry.line, 0, 0])
|
||||
|
||||
" Ensure folds are opened
|
||||
normal! zv
|
||||
endfunction
|
||||
|
||||
function! s:toc_toggle_numbers() "{{{1
|
||||
if g:vimtex_toc_numbers
|
||||
let g:vimtex_toc_numbers = 0
|
||||
else
|
||||
let g:vimtex_toc_numbers = 1
|
||||
endif
|
||||
|
||||
call vimtex_toc#refresh()
|
||||
endfunction
|
||||
|
||||
function! s:toc_inc_secnumdepth() "{{{1
|
||||
let b:toc_secnumdepth = min([b:toc_secnumdepth + 1, 5])
|
||||
let g:vimtex_toc_secnumdepth = b:toc_secnumdepth
|
||||
call vimtex_toc#refresh()
|
||||
endfunction
|
||||
|
||||
function! s:toc_dec_secnumdepth() "{{{1
|
||||
let b:toc_secnumdepth = max([b:toc_secnumdepth - 1, -2])
|
||||
let g:vimtex_toc_secnumdepth = b:toc_secnumdepth
|
||||
call vimtex_toc#refresh()
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
" vim: fdm=marker sw=2
|
@ -1,23 +0,0 @@
|
||||
" vimtex - LaTeX plugin for Vim
|
||||
"
|
||||
" Maintainer: Karl Yngve Lervåg
|
||||
" Email: karl.yngve@gmail.com
|
||||
"
|
||||
|
||||
syntax match TocHelpText /^.*: .*/
|
||||
syntax match TocNum /^\(\([A-Z]\+\>\|\d\+\)\(\.\d\+\)*\)\?\s*/ contained
|
||||
syntax match TocSec0 /^.*0$/ contains=TocNum,@Tex
|
||||
syntax match TocSec1 /^.*1$/ contains=TocNum,@Tex
|
||||
syntax match TocSec2 /^.*2$/ contains=TocNum,@Tex
|
||||
syntax match TocSec3 /^.*3$/ contains=TocNum,@Tex
|
||||
syntax match TocSec4 /^.*4$/ contains=TocNum,@Tex
|
||||
|
||||
highlight link TocHelpText helpVim
|
||||
highlight link TocNum Number
|
||||
highlight link TocSec0 Title
|
||||
highlight link TocSec1 Normal
|
||||
highlight link TocSec2 helpVim
|
||||
highlight link TocSec3 NonText
|
||||
highlight link TocSec4 Comment
|
||||
|
||||
" vim: fdm=marker sw=2
|
Loading…
x
Reference in New Issue
Block a user