vimtex/autoload/latex/toc.vim
2014-07-09 12:13:26 +02:00

151 lines
3.5 KiB
VimL

" {{{1 latex#toc#init
function! latex#toc#init(initialized)
if g:latex_mappings_enabled && g:latex_toc_enabled
nnoremap <silent><buffer> <LocalLeader>lt :call latex#toc#open()<cr>
nnoremap <silent><buffer> <LocalLeader>lT :call latex#toc#toggle()<cr>
endif
endfunction
" {{{1 latex#toc#open
function! latex#toc#open()
" Check if buffer exists
let winnr = bufwinnr(bufnr('LaTeX TOC'))
if winnr >= 0
silent execute winnr . 'wincmd w'
return
endif
" Store buffer and file info
let calling_buf = bufnr('%')
let calling_file = expand('%:p')
" Resize if wanted
if g:latex_toc_resize
silent exe "set columns+=" . g:latex_toc_width
endif
" Parse TOC data
let toc = s:read_toc(g:latex#data[b:latex.id].tex)
"let closest_index = s:find_closest_section(toc, calling_file)
" Create TOC window
silent exe g:latex_toc_split_side g:latex_toc_width . 'vnew LaTeX\ TOC'
let b:toc = toc
let b:toc_numbers = 1
let b:calling_win = bufwinnr(calling_buf)
" Add TOC entries
for entry in toc
call append('$', entry['number'] . "\t" . entry['text'])
endfor
" Add help info
if !g:latex_toc_hide_help
call append('$', "")
call append('$', "<Esc>/q: close")
call append('$', "<Space>: jump")
call append('$', "<Enter>: jump and close")
call append('$', "s: hide numbering")
endif
0delete _
" Jump to the closest section
"execute 'normal! ' . (closest_index + 1) . 'G'
" Set filetype and lock buffer
setlocal filetype=latextoc
setlocal nomodifiable
endfunction
" {{{1 latex#toc#toggle
function! latex#toc#toggle()
if bufwinnr(bufnr('LaTeX TOC')) >= 0
if g:latex_toc_resize
silent exe "set columns-=" . g:latex_toc_width
endif
silent execute 'bwipeout' . bufnr('LaTeX TOC')
else
call latex#toc#open()
silent execute 'wincmd w'
endif
endfunction
" }}}1
" {{{1 s:read_toc
function! s:read_toc(texfile, ...)
" Allow recursion
if a:0 != 2
let toc = []
else
let toc = a:1
endif
let lnum = 1
for line in readfile(a:texfile)
let line_stat = s:test_line
if s:test_line(line)
call add(toc, s:parse_line(line, lnum, a:texfile))
endif
let lnum += 1
endfor
return toc
endfunction
" {{{1 s:test_line
function! s:test_line(line)
return line =~#
endfunction
" {{{1 s:parse_input_line
function! s:parse_input_line(line)
endfunction
" {{{1 s:parse_toc_line
function! s:parse_toc_line(line, lnum, file)
return {
\ 'title': "sec",
\ 'file': a:texfile,
\ 'line': a:lnum,
\ }
endfunction
" {{{1 s:find_closest_section
"
" 1. Binary search for the closest section
" 2. Return the index of the TOC entry
"
function! s:find_closest_section(toc, file)
if !has_key(a:toc.fileindices, a:file)
return
endif
let imax = len(a:toc.fileindices[a:file])
if imax > 0
let imin = 0
while imin < imax - 1
let i = (imax + imin) / 2
let tocindex = a:toc.fileindices[a:file][i]
let entry = a:toc.data[tocindex]
let titlestr = substitute(entry['text'],
\ '\\\w*\>\s*\%({[^}]*}\)\?', '.*', 'g')
let titlestr = escape(titlestr, '\')
let titlestr = substitute(titlestr, ' ', '\\_\\s\\+', 'g')
let [lnum, cnum]
\ = searchpos('\\'.entry['level'].'\_\s*{'.titlestr.'}', 'cnW')
if lnum
let imax = i
else
let imin = i
endif
endwhile
return a:toc.fileindices[a:file][imin]
else
return 0
endif
endfunction
" }}}1
" vim: fdm=marker