A lot of convenient restructuring

This commit is contained in:
Karl Yngve Lervåg 2015-06-06 23:49:28 +02:00
parent a76cba6330
commit 6d7b0abd16
14 changed files with 783 additions and 560 deletions

View File

@ -4,155 +4,73 @@
" Email: karl.yngve@gmail.com
"
" vimtex is not initialized until vimtex#init() has been run once
" {{{1 Initialization variables
"
" The flag s:initialized is set to 1 after vimtex has been initialized to
" prevent errors if the scripts are loaded more than once (e.g. when opening
" more than one LaTeX buffer in one vim instance). Thus it allows us to
" distinguish between global initialization and buffer initialization.
"
if !exists('s:initialized')
let s:initialized = 0
endif
"
" Define list of vimtex modules
"
if !exists('s:modules')
let s:modules = map(
\ split(
\ globpath(
\ fnamemodify(expand('<sfile>'), ':r'),
\ '*.vim'),
\ '\n'),
\ 'fnamemodify(v:val, '':t:r'')')
endif
" }}}1
"
" Main initialization function
"
function! vimtex#init() " {{{1
call s:init_options()
call s:init_environment()
call vimtex#toc#init(s:initialized)
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)
call vimtex#latexmk#init(s:initialized)
call vimtex#complete#init(s:initialized)
call vimtex#mappings#init(s:initialized)
"
" First initialize buffer options and construct (if necessary) the vimtex
" data blob.
"
call s:init_buffer()
"
" This variable is used to allow a distinction between global and buffer
" initialization
" Then we initialize the modules. This is done in three steps:
"
" 1. Initialize options (load default options if not otherwise set). This is
" only done once for each vim session.
"
" 2. Initialize module scripts (set script variables and similar). This is
" also only done once for each vim session.
"
" 3. Initialize module for current buffer. This is done for each new LaTeX
" buffer.
"
if !s:initialized
call s:init_modules('options')
call s:init_modules('script')
endif
call s:init_modules('buffer')
let s:initialized = 1
endfunction
" }}}1
function! vimtex#info(global) " {{{1
if !s:initialized
echoerr 'Error: vimtex has not been initialized!'
return
endif
if a:global
let n = 0
for data in g:vimtex_data
let d = deepcopy(data)
for f in ['aux', 'out', 'log']
silent execute 'let d.' . f . ' = data.' . f . '()'
endfor
call vimtex#echo#formatted([
\ "\n\ng:vimtex_data[", ['VimtexSuccess', n], '] : ',
\ ['VimtexSuccess', remove(d, 'name') . "\n"]])
call s:print_dict(d)
let n += 1
endfor
else
let d = deepcopy(b:vimtex)
for f in ['aux', 'out', 'log']
silent execute 'let d.' . f . ' = b:vimtex.' . f . '()'
endfor
call vimtex#echo#formatted([
\ 'b:vimtex : ',
\ ['VimtexSuccess', remove(d, 'name') . "\n"]])
call s:print_dict(d)
endif
endfunction
" }}}1
function! vimtex#wordcount(detailed) " {{{1
" Run texcount, save output to lines variable
let cmd = 'cd ' . vimtex#util#fnameescape(b:vimtex.root)
let cmd .= '; texcount -nosub -sum '
let cmd .= a:detailed > 0 ? '-inc ' : '-merge '
let cmd .= vimtex#util#fnameescape(b:vimtex.base)
let lines = split(system(cmd), '\n')
" Create wordcount window
if bufnr('TeXcount') >= 0
bwipeout TeXcount
endif
split TeXcount
" Add lines to buffer
for line in lines
call append('$', printf('%s', line))
endfor
0delete _
" Set mappings
nnoremap <buffer> <silent> q :bwipeout<cr>
" Set buffer options
setlocal bufhidden=wipe
setlocal buftype=nofile
setlocal cursorline
setlocal listchars=
setlocal nobuflisted
setlocal nolist
setlocal nospell
setlocal noswapfile
setlocal nowrap
setlocal tabstop=8
setlocal nomodifiable
" Set highlighting
syntax match TexcountText /^.*:.*/ contains=TexcountValue
syntax match TexcountValue /.*:\zs.*/
highlight link TexcountText VimtexMsg
highlight link TexcountValue Constant
endfunction
" }}}1
function! s:init_environment() " {{{1
" Initialize container for data blobs if it does not exist
let g:vimtex_data = get(g:, 'vimtex_data', [])
" Get main file number and check if data blob already exists
let main = s:get_main()
let id = s:get_id(main)
if id >= 0
" Link to existing blob
let b:vimtex_id = id
let b:vimtex = g:vimtex_data[id]
else
" Create new blob
let b:vimtex = {}
let b:vimtex.tex = main
let b:vimtex.root = fnamemodify(b:vimtex.tex, ':h')
let b:vimtex.base = fnamemodify(b:vimtex.tex, ':t')
let b:vimtex.name = fnamemodify(b:vimtex.tex, ':t:r')
function b:vimtex.aux() dict
return s:get_main_ext(self, 'aux')
endfunction
function b:vimtex.log() dict
return s:get_main_ext(self, 'log')
endfunction
function b:vimtex.out() dict
return s:get_main_ext(self, 'pdf')
endfunction
call add(g:vimtex_data, b:vimtex)
let b:vimtex_id = len(g:vimtex_data) - 1
endif
" Define commands
command! -buffer -bang VimtexInfo call vimtex#info(<q-bang> == "!")
command! -buffer -bang VimtexWordCount call vimtex#wordcount(<q-bang> == "!")
" Define mappings
nnoremap <buffer> <plug>(vimtex-info) :call vimtex#info(0)<cr>
endfunction
function! s:init_options() " {{{1
"
" Auxilliary initialization functions
"
function! s:init_buffer() " {{{1
"
" First we set some vim options
"
let s:save_cpo = &cpo
set cpo&vim
@ -199,6 +117,59 @@ function! s:init_options() " {{{1
let &cpo = s:save_cpo
unlet s:save_cpo
"
" Next we initialize the data blob
"
" Create container for data blobs if it does not exist
let g:vimtex_data = get(g:, 'vimtex_data', [])
" Get main file number and check if data blob already exists
let main = s:get_main()
let id = s:get_id(main)
if id >= 0
" Link to existing blob
let b:vimtex_id = id
let b:vimtex = g:vimtex_data[id]
else
" Create new blob
let b:vimtex = {}
let b:vimtex.tex = main
let b:vimtex.root = fnamemodify(b:vimtex.tex, ':h')
let b:vimtex.base = fnamemodify(b:vimtex.tex, ':t')
let b:vimtex.name = fnamemodify(b:vimtex.tex, ':t:r')
function b:vimtex.aux() dict
return s:get_main_ext(self, 'aux')
endfunction
function b:vimtex.log() dict
return s:get_main_ext(self, 'log')
endfunction
function b:vimtex.out() dict
return s:get_main_ext(self, 'pdf')
endfunction
call add(g:vimtex_data, b:vimtex)
let b:vimtex_id = len(g:vimtex_data) - 1
endif
"
" Finally we define commands and mappings
"
" Define commands
command! -buffer -bang VimtexInfo call vimtex#info(<q-bang> == "!")
command! -buffer -bang VimtexWordCount call vimtex#wordcount(<q-bang> == "!")
" Define mappings
nnoremap <buffer> <plug>(vimtex-info) :call vimtex#info(0)<cr>
endfunction
" }}}1
function! s:init_modules(initmode) " {{{1
for module in s:modules
execute 'call vimtex#' . module . '#init_' . a:initmode . '()'
endfor
endfunction
" }}}1
@ -343,6 +314,87 @@ endfunction
" }}}1
"
" Simple utility features
"
function! vimtex#info(global) " {{{1
if !s:initialized
echoerr 'Error: vimtex has not been initialized!'
return
endif
if a:global
let n = 0
for data in g:vimtex_data
let d = deepcopy(data)
for f in ['aux', 'out', 'log']
silent execute 'let d.' . f . ' = data.' . f . '()'
endfor
call vimtex#echo#formatted([
\ "\n\ng:vimtex_data[", ['VimtexSuccess', n], '] : ',
\ ['VimtexSuccess', remove(d, 'name') . "\n"]])
call s:print_dict(d)
let n += 1
endfor
else
let d = deepcopy(b:vimtex)
for f in ['aux', 'out', 'log']
silent execute 'let d.' . f . ' = b:vimtex.' . f . '()'
endfor
call vimtex#echo#formatted([
\ 'b:vimtex : ',
\ ['VimtexSuccess', remove(d, 'name') . "\n"]])
call s:print_dict(d)
endif
endfunction
" }}}1
function! vimtex#wordcount(detailed) " {{{1
" Run texcount, save output to lines variable
let cmd = 'cd ' . vimtex#util#fnameescape(b:vimtex.root)
let cmd .= '; texcount -nosub -sum '
let cmd .= a:detailed > 0 ? '-inc ' : '-merge '
let cmd .= vimtex#util#fnameescape(b:vimtex.base)
let lines = split(system(cmd), '\n')
" Create wordcount window
if bufnr('TeXcount') >= 0
bwipeout TeXcount
endif
split TeXcount
" Add lines to buffer
for line in lines
call append('$', printf('%s', line))
endfor
0delete _
" Set mappings
nnoremap <buffer> <silent> q :bwipeout<cr>
" Set buffer options
setlocal bufhidden=wipe
setlocal buftype=nofile
setlocal cursorline
setlocal listchars=
setlocal nobuflisted
setlocal nolist
setlocal nospell
setlocal noswapfile
setlocal nowrap
setlocal tabstop=8
setlocal nomodifiable
" Set highlighting
syntax match TexcountText /^.*:.*/ contains=TexcountValue
syntax match TexcountValue /.*:\zs.*/
highlight link TexcountText VimtexMsg
highlight link TexcountValue Constant
endfunction
" }}}1
function! s:print_dict(dict, ...) " {{{1
let level = a:0 > 0 ? a:1 : 0

View File

@ -4,7 +4,7 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#change#init(initialized) " {{{1
function! vimtex#change#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_change_complete_envs', [
\ 'itemize',
\ 'enumerate',
@ -18,28 +18,44 @@ function! vimtex#change#init(initialized) " {{{1
\ 'split',
\ '\[',
\ ])
endfunction
" Define mappings
" }}}1
function! vimtex#change#init_script() " {{{1
endfunction
" }}}1
function! vimtex#change#init_buffer() " {{{1
nnoremap <silent><buffer> <plug>(vimtex-delete-env)
\ :call vimtex#change#env('')<cr>
nnoremap <silent><buffer> <plug>(vimtex-delete-cmd) vaBom`o<esc>xg``xdF\
\:silent! call repeat#set("\<plug>(vimtex-delete-cmd)", v:count)<cr>
nnoremap <silent><buffer> <plug>(vimtex-change-env)
\ :call vimtex#change#env_prompt()<cr>
nnoremap <silent><buffer> <plug>(vimtex-change-cmd)
\ :call vimtex#change#command()<cr>
nnoremap <silent><buffer> <plug>(vimtex-toggle-star)
\ :call vimtex#change#toggle_env_star()<cr>
nnoremap <silent><buffer> <plug>(vimtex-toggle-delim)
\ :call vimtex#change#toggle_delim()<cr>
nnoremap <silent><buffer> <plug>(vimtex-create-cmd)
\ :call vimtex#change#to_command()<cr>i
inoremap <silent><buffer> <plug>(vimtex-create-cmd)
\ <c-r>=vimtex#change#to_command()<cr>
inoremap <silent><buffer> <plug>(vimtex-close-env)
\ <c-r>=vimtex#change#close_environment()<cr>
endfunction
" }}}1
function! vimtex#change#command() " {{{1
let pos_save = getpos('.')
let savereg = @a

View File

@ -4,11 +4,10 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#complete#init(initialized) " {{{1
function! vimtex#complete#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_complete_enabled', 1)
if !g:vimtex_complete_enabled | return | endif
" Set default options
call vimtex#util#set_default('g:vimtex_complete_close_braces', 0)
call vimtex#util#set_default('g:vimtex_complete_recursive_bib', 0)
call vimtex#util#set_default('g:vimtex_complete_patterns',
@ -16,8 +15,14 @@ function! vimtex#complete#init(initialized) " {{{1
\ 'ref' : '\C\\v\?\(auto\|eq\|page\|[cC]\|labelc\)\?ref\*\?\_\s*{[^{}]*',
\ 'bib' : '\C\\\a*cite\a*\*\?\(\[[^\]]*\]\)*\_\s*{[^{}]*',
\ })
endfunction
" }}}1
function! vimtex#complete#init_script() " {{{1
if !g:vimtex_complete_enabled | return | endif
" Check if bibtex is available
let s:bibtex = 1
if !executable('bibtex')
call vimtex#echo#warning('vimtex warning')
call vimtex#echo#warning(' bibtex completion is not available!',
@ -37,9 +42,44 @@ function! vimtex#complete#init(initialized) " {{{1
let s:bibtex = 0
endif
" Define auxiliary variable for completion
let s:completion_type = ''
let s:type_length = 0
" Define some regular expressions
let s:nocomment = '\v%(%(\\@<!%(\\\\)*)@<=\%.*)@<!'
let s:re_bibs = '''' . s:nocomment
let s:re_bibs .= '\\(bibliography|add(bibresource|globalbib|sectionbib))'
let s:re_bibs .= '\m\s*{\zs[^}]\+\ze}'''
let s:re_incsearch = '''' . s:nocomment
let s:re_incsearch .= '\\%(input|include)'
let s:re_incsearch .= '\m\s*{\zs[^}]\+\ze}'''
"
" s:label_cache is a dictionary that maps filenames to tuples of the form
"
" [time, labels, inputs]
"
" where time is modification time of the cache entry, labels is a list like
" returned by extract_labels, and inputs is a list like returned by
" s:extract_inputs.
"
let s:label_cache = {}
endfunction
" The variable s:bstfile must be defined in script level in order to expand
" into the script file name.
let s:bstfile = expand('<sfile>:p:h') . '/vimcomplete'
" }}}1
function! vimtex#complete#init_buffer() " {{{1
if !g:vimtex_complete_enabled | return | endif
setlocal omnifunc=vimtex#complete#omnifunc
endfunction
" }}}1
function! vimtex#complete#omnifunc(findstart, base) " {{{1
if a:findstart
"
@ -78,10 +118,7 @@ function! vimtex#complete#omnifunc(findstart, base) " {{{1
endif
endfunction
" Define auxiliary variables for completion
let s:bibtex = 1
let s:completion_type = ''
" }}}1
function! vimtex#complete#labels(regex) " {{{1
let labels = s:labels_get(b:vimtex.aux())
let matches = filter(copy(labels), 'v:val[0] =~ ''' . a:regex . '''')
@ -120,6 +157,7 @@ function! vimtex#complete#labels(regex) " {{{1
return suggestions
endfunction
" }}}1
function! vimtex#complete#bibtex(regexp) " {{{1
let res = []
@ -150,24 +188,13 @@ function! vimtex#complete#bibtex(regexp) " {{{1
return res
endfunction
" }}}1
" {{{1 Bibtex completion
" Define some regular expressions
let s:nocomment = '\v%(%(\\@<!%(\\\\)*)@<=\%.*)@<!'
let s:re_bibs = '''' . s:nocomment
let s:re_bibs .= '\\(bibliography|add(bibresource|globalbib|sectionbib))'
let s:re_bibs .= '\m\s*{\zs[^}]\+\ze}'''
let s:re_incsearch = '''' . s:nocomment
let s:re_incsearch .= '\\%(input|include)'
let s:re_incsearch .= '\m\s*{\zs[^}]\+\ze}'''
" Define some auxiliary variables
let s:bstfile = expand('<sfile>:p:h') . '/vimcomplete'
let s:type_length = 0
function! s:bibtex_search(regexp) " {{{2
"
" Bibtex completion
"
function! s:bibtex_search(regexp) " {{{1
let res = []
" The bibtex completion seems to require that we are in the project root
@ -245,7 +272,8 @@ function! s:bibtex_search(regexp) " {{{2
return res
endfunction
function! s:bibtex_find_bibs(...) " {{{2
" }}}1
function! s:bibtex_find_bibs(...) " {{{1
if a:0
let file = a:1
else
@ -283,21 +311,12 @@ function! s:bibtex_find_bibs(...) " {{{2
return bibfiles
endfunction
" }}}2
" }}}1
" {{{1 Label completion
"
" s:label_cache is a dictionary that maps filenames to tuples of the form
"
" [ time, labels, inputs ]
"
" where time is modification time of the cache entry, labels is a list like
" returned by extract_labels, and inputs is a list like returned by
" s:extract_inputs.
"
let s:label_cache = {}
function! s:labels_get(file) " {{{2
"
" Label completion
"
function! s:labels_get(file) " {{{1
"
" s:labels_get compares modification time of each entry in the label cache
" and updates it if necessary. During traversal of the label cache, all
@ -331,7 +350,8 @@ function! s:labels_get(file) " {{{2
return labels
endfunction
function! s:labels_extract(file) " {{{2
" }}}1
function! s:labels_extract(file) " {{{1
"
" Searches file for commands of the form
"
@ -345,20 +365,21 @@ function! s:labels_extract(file) " {{{2
let lines = filter(lines, 'v:val !~# ''@cref''')
let lines = map(lines, 'vimtex#util#convert_back(v:val)')
for line in lines
let tree = vimtex#util#tex2tree(line)
let tree = s:tex2tree(line)
if type(tree[2][0]) == type([])
\ && !empty(tree[2][0])
call add(matches, [
\ vimtex#util#tree2tex(tree[1][0]),
\ vimtex#util#tree2tex(tree[2][0][0]),
\ vimtex#util#tree2tex(tree[2][1][0]),
\ s:tree2tex(tree[1][0]),
\ s:tree2tex(tree[2][0][0]),
\ s:tree2tex(tree[2][1][0]),
\ ])
endif
endfor
return matches
endfunction
function! s:labels_extract_inputs(file) " {{{2
" }}}1
function! s:labels_extract_inputs(file) " {{{1
let matches = []
let root = fnamemodify(a:file, ':p:h') . '/'
for input in filter(readfile(a:file), 'v:val =~# ''\\@input{''')
@ -370,12 +391,56 @@ function! s:labels_extract_inputs(file) " {{{2
return matches
endfunction
" }}}2
" }}}1
"
" Utility functions
"
function! s:next_chars_match(regex) " {{{1
return strpart(getline('.'), col('.') - 1) =~ a:regex
endfunction
" }}}1
function! s:tex2tree(str) " {{{1
let tree = []
let i1 = 0
let i2 = -1
let depth = 0
while i2 < len(a:str)
let i2 = match(a:str, '[{}]', i2 + 1)
if i2 < 0
let i2 = len(a:str)
endif
if i2 >= len(a:str) || a:str[i2] ==# '{'
if depth == 0
let item = substitute(strpart(a:str, i1, i2 - i1),
\ '^\s*\|\s*$', '', 'g')
if !empty(item)
call add(tree, item)
endif
let i1 = i2 + 1
endif
let depth += 1
else
let depth -= 1
if depth == 0
call add(tree, s:tex2tree(strpart(a:str, i1, i2 - i1)))
let i1 = i2 + 1
endif
endif
endwhile
return tree
endfunction
" }}}1
function! s:tree2tex(tree) " {{{1
if type(a:tree) == type('')
return a:tree
else
return '{' . join(map(a:tree, 's:tree2tex(v:val)'), '') . '}'
endif
endfunction
" }}}1
" vim: fdm=marker sw=2

View File

@ -4,12 +4,22 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#echo#init(initialized) " {{{1
function! vimtex#echo#init_options() " {{{1
endfunction
" }}}1
function! vimtex#echo#init_script() " {{{1
highlight link VimtexMsg ModeMsg
highlight link VimtexSuccess Statement
highlight link VimtexWarning WarningMsg
endfunction
" }}}1
function! vimtex#echo#init_buffer() " {{{1
endfunction
" }}}1
function! vimtex#echo#echo(message, ...) " {{{1
let hl = len(a:000) > 0 ? a:0 : 'VimtexMsg'
execute 'echohl' hl

View File

@ -4,11 +4,10 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#fold#init(initialized) " {{{1
function! vimtex#fold#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_fold_enabled', 1)
if !g:vimtex_fold_enabled | return | endif
" Set default options
call vimtex#util#set_default('g:vimtex_fold_automatic', 0)
call vimtex#util#set_default('g:vimtex_fold_preamble', 1)
call vimtex#util#set_default('g:vimtex_fold_envs', 1)
@ -27,11 +26,34 @@ function! vimtex#fold#init(initialized) " {{{1
\ 'subsection',
\ 'subsubsection',
\ ])
endfunction
" }}}1
function! vimtex#fold#init_script() " {{{1
if !g:vimtex_fold_enabled | return | endif
" Define some script variables
let s:parts = '\v^\s*(\\|\% Fake)(' . join(g:vimtex_fold_parts, '|') . ')>'
let s:secs = '\v^\s*(\\|\% Fake)(' . join(g:vimtex_fold_sections, '|') . ')>'
" For automatic folding with foldmethod=expr:
" The foldexpr function returns "=" for most lines, which means it can
" become slow for large files. The following is a hack that is based on
" this reply to a discussion on the Vim Developer list:
" http://permalink.gmane.org/gmane.editors.vim.devel/14100
if g:vimtex_fold_automatic
augroup latex_fold
autocmd!
autocmd InsertEnter *.tex call FdmSave()
autocmd InsertLeave *.tex call FdmRestore()
augroup END
endif
endfunction
" }}}1
function! vimtex#fold#init_buffer() " {{{1
if !g:vimtex_fold_enabled | return | endif
" Set fold options
setl foldmethod=expr
setl foldexpr=vimtex#fold#level(v:lnum)
@ -46,20 +68,7 @@ function! vimtex#fold#init(initialized) " {{{1
" Set options for automatic/manual mode
if g:vimtex_fold_automatic
" For some reason, foldmethod=expr makes undo slow (at least in some cases)
nnoremap <silent><buffer> u :call FdmSave()<cr>u:call FdmRestore()<cr>
" The foldexpr function returns "=" for most lines, which means it can
" become slow for large files. The following is a hack that is based on
" this reply to a discussion on the Vim Developer list:
" http://permalink.gmane.org/gmane.editors.vim.devel/14100
if !a:initialized
augroup latex_fold
autocmd!
autocmd InsertEnter *.tex call FdmSave()
autocmd InsertLeave *.tex call FdmRestore()
augroup END
endif
else
augroup latex_fold
autocmd!
@ -69,6 +78,8 @@ function! vimtex#fold#init(initialized) " {{{1
endif
endfunction
" }}}1
function! vimtex#fold#refresh(map) " {{{1
" Parse tex file to dynamically set the sectioning fold levels
let b:vimtex_fold_parts = s:parse_folded()

View File

@ -4,7 +4,7 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#index#init(initialized) " {{{1
function! vimtex#index#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_index_hide_line_numbers', 1)
call vimtex#util#set_default('g:vimtex_index_resize', 0)
call vimtex#util#set_default('g:vimtex_index_show_help', 1)
@ -13,6 +13,15 @@ function! vimtex#index#init(initialized) " {{{1
endfunction
" }}}1
function! vimtex#index#init_script() " {{{1
endfunction
" }}}1
function! vimtex#index#init_buffer() " {{{1
endfunction
" }}}1
function! vimtex#index#open(bufname) " {{{1
let winnr = bufwinnr(bufnr(a:bufname))
if winnr >= 0

View File

@ -4,12 +4,25 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#labels#init(initialized) " {{{1
function! vimtex#labels#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_labels_enabled', 1)
endfunction
" }}}1
function! vimtex#labels#init_script() " {{{1
if !g:vimtex_labels_enabled | return | endif
" Set some constants
let s:name = 'Table of labels (vimtex)'
let s:preamble = 1
let s:re_input = '\v^\s*\\%(input|include)\s*\{'
let s:re_input_file = s:re_input . '\zs[^\}]+\ze}'
let s:re_label = '\v\\label\{'
let s:re_label_title = s:re_label . '\zs.{-}\ze\}?\s*$'
endfunction
" }}}1
function! vimtex#labels#init_buffer() " {{{1
if !g:vimtex_labels_enabled | return | endif
" Define commands
command! -buffer VimtexLabelsOpen call vimtex#labels#open()
@ -21,6 +34,7 @@ function! vimtex#labels#init(initialized) " {{{1
endfunction
" }}}1
function! vimtex#labels#open() " {{{1
if vimtex#index#open(s:name) | return | endif
@ -42,6 +56,7 @@ function! vimtex#labels#open() " {{{1
call vimtex#index#create(index)
endfunction
" }}}1
function! vimtex#labels#toggle() " {{{1
if vimtex#index#open(s:name)
call vimtex#index#close(s:name)
@ -92,16 +107,6 @@ endfunction
" }}}1
" {{{1 TOL variables
let s:preamble = 1
let s:re_input = '\v^\s*\\%(input|include)\s*\{'
let s:re_input_file = s:re_input . '\zs[^\}]+\ze}'
let s:re_label = '\v\\label\{'
let s:re_label_title = s:re_label . '\zs.{-}\ze\}?\s*$'
" }}}1
function! s:gather_labels(file) " {{{1
let tac = []
let lnum = 0

View File

@ -4,13 +4,11 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#latexmk#init(initialized) " {{{1
function! vimtex#latexmk#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_latexmk_enabled', 1)
call vimtex#util#set_default('g:vimtex_latexmk_build_dir', '')
if !g:vimtex_latexmk_enabled | return | endif
if s:system_incompatible() | return | endif
" Set default options
call vimtex#util#set_default('g:vimtex_latexmk_background', 0)
call vimtex#util#set_default('g:vimtex_latexmk_callback', 1)
call vimtex#util#set_default('g:vimtex_latexmk_continuous', 1)
@ -20,10 +18,26 @@ function! vimtex#latexmk#init(initialized) " {{{1
call vimtex#util#set_default('g:vimtex_quickfix_ignored_warnings', [])
call vimtex#util#set_default('g:vimtex_quickfix_mode', '2')
call vimtex#util#set_default('g:vimtex_quickfix_open_on_warning', '1')
call vimtex#util#error_deprecated('g:vimtex_build_dir')
call vimtex#util#error_deprecated('g:vimtex_latexmk_autojump')
call vimtex#util#error_deprecated('g:vimtex_latexmk_output')
call vimtex#util#error_deprecated('g:vimtex_latexmk_quickfix')
endfunction
" }}}1
function! vimtex#latexmk#init_script() " {{{1
call s:check_system_compatibility()
if !g:vimtex_latexmk_enabled | return | endif
" Ensure that all latexmk processes are stopped when vim exits
if g:vimtex_latexmk_continuous
augroup latex_latexmk
autocmd!
autocmd VimLeave * call vimtex#latexmk#stop_all()
augroup END
endif
endfunction
" }}}1
function! vimtex#latexmk#init_buffer() " {{{1
if !g:vimtex_latexmk_enabled | return | endif
" Set compiler (this defines the errorformat)
compiler latexmk
@ -57,27 +71,16 @@ function! vimtex#latexmk#init(initialized) " {{{1
nnoremap <buffer> <plug>(vimtex-status-all) :call vimtex#latexmk#status(1)<cr>
nnoremap <buffer> <plug>(vimtex-lacheck) :call vimtex#latexmk#lacheck()<cr>
" The remaining part is only relevant for continuous mode
if !g:vimtex_latexmk_continuous | return | endif
" Ensure that all latexmk processes are stopped when vim exits
" Note: Only need to define this once, globally.
if !a:initialized
" Kill running latexmk process if all buffers for a latex project are closed
if g:vimtex_latexmk_continuous
augroup latex_latexmk
autocmd!
autocmd VimLeave * call vimtex#latexmk#stop_all()
autocmd BufUnload <buffer> call s:stop_buffer()
augroup END
endif
" If all buffers for a given latex project are closed, kill latexmk
" Note: This must come after the above so that the autocmd group is properly
" refreshed if necessary
augroup latex_latexmk
autocmd BufUnload <buffer> call s:stop_buffer()
augroup END
endfunction
" }}}1
function! vimtex#latexmk#callback(status) " {{{1
call vimtex#latexmk#errors_open(0)
@ -489,24 +492,28 @@ function! s:stop_buffer() " {{{1
endif
endfunction
function! s:system_incompatible() " {{{1
function! s:check_system_compatibility() " {{{1
"
" Check for required executables
"
if has('win32')
let required = ['latexmk']
else
let required = ['latexmk', 'pgrep']
endif
let missing = filter(required, '!executable(v:val)')
"
" Check for required executables
" Disable latexmk if required programs are missing
"
for cmd in required
if !executable(cmd)
call vimtex#echo#warning('vimtex warning: ')
call vimtex#echo#warning(' vimtex#latexmk was not initialized', 'None')
if len(missing) > 0
call vimtex#echo#warning('vimtex warning: ')
call vimtex#echo#warning(' vimtex#latexmk was not initialized', 'None')
for cmd in missing
call vimtex#echo#warning(' ' . cmd . ' is not executable', 'None')
return 1
endif
endfor
endfor
let g:vimtex_latexmk_enabled = 0
endif
endfunction
" }}}1

View File

@ -4,8 +4,16 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#mappings#init(initialized)
function! vimtex#mappings#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_mappings_enabled', 1)
endfunction
" }}}1
function! vimtex#mappings#init_script() " {{{1
endfunction
" }}}1
function! vimtex#mappings#init_buffer() " {{{1
if !g:vimtex_mappings_enabled | return | endif
nmap <silent><buffer> <localleader>li <plug>(vimtex-info)
@ -80,4 +88,6 @@ function! vimtex#mappings#init(initialized)
endif
endfunction
" }}}1
" vim: fdm=marker sw=2

View File

@ -4,14 +4,81 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#motion#init(initialized) " {{{1
function! vimtex#motion#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_motion_enabled', 1)
if !g:vimtex_motion_enabled | return | endif
" Set default options
call vimtex#util#set_default('g:vimtex_motion_matchparen', 1)
endfunction
" }}}1
function! vimtex#motion#init_script() " {{{1
if !g:vimtex_motion_enabled | return | endif
" Highlight matching parens ($, (), ...)
if g:vimtex_motion_matchparen
augroup latex_motion
autocmd!
" Disable matchparen autocommands
autocmd BufEnter *.tex
\ if !exists("g:loaded_matchparen") || !g:loaded_matchparen
\ | runtime plugin/matchparen.vim
\ | endif
autocmd BufEnter *.tex
\ 3match none | unlet! g:loaded_matchparen | au! matchparen
" Enable latex matchparen functionality
autocmd! CursorMoved *.tex call s:highlight_matching_pair(1)
autocmd! CursorMovedI *.tex call s:highlight_matching_pair()
augroup END
endif
"
" Define patterns used by motion.vim
"
" No preceding backslash
let s:notbslash = '\%(\\\@<!\%(\\\\\)*\)\@<='
" Not in a comment
let s:notcomment = '\%(\%(\\\@<!\%(\\\\\)*\)\@<=%.*\)\@<!'
" Patterns to match opening and closing delimiters/environments
let s:delimiters_open = [
\ '{',
\ '(',
\ '\[',
\ '\\{',
\ '\\(',
\ '\\\[',
\ '\\\Cbegin\s*{.\{-}}',
\ '\\\Cleft\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\((\|\[\|\\{\)',
\ ]
let s:delimiters_close = [
\ '}',
\ ')',
\ '\]',
\ '\\}',
\ '\\)',
\ '\\\]',
\ '\\\Cend\s*{.\{-}}',
\ '\\\Cright\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\()\|\]\|\\}\)',
\ ]
let s:delimiters = join(s:delimiters_open + s:delimiters_close, '\|')
let s:delimiters = '\(' . s:delimiters . '\|\$\)'
" Pattern to match section/chapter/...
let s:section = s:notcomment . '\v\s*\\'
let s:section .= '((sub)*section|chapter|part|'
let s:section .= 'appendix|(front|back|main)matter)>'
endfunction
" }}}1
function! vimtex#motion#init_buffer() " {{{1
if !g:vimtex_motion_enabled | return | endif
" Define mappings
nnoremap <buffer> <sid>(v) v
nnoremap <silent><buffer> <plug>(vimtex-%) :call vimtex#motion#find_matching_pair()<cr>
nnoremap <silent><buffer> <plug>(vimtex-]]) :call vimtex#motion#next_section(0,0,0)<cr>
@ -40,26 +107,10 @@ function! vimtex#motion#init(initialized) " {{{1
onoremap <silent><buffer> <plug>(vimtex-a$) :execute "normal \<sid>(v)\<plug>(vimtex-a$)"<cr>
onoremap <silent><buffer> <plug>(vimtex-id) :execute "normal \<sid>(v)\<plug>(vimtex-id)"<cr>
onoremap <silent><buffer> <plug>(vimtex-ad) :execute "normal \<sid>(v)\<plug>(vimtex-ad)"<cr>
" Highlight matching parens ($, (), ...)
if !a:initialized && g:vimtex_motion_matchparen
augroup latex_motion
autocmd!
" Disable matchparen autocommands
autocmd BufEnter *.tex
\ if !exists("g:loaded_matchparen") || !g:loaded_matchparen
\ | runtime plugin/matchparen.vim
\ | endif
autocmd BufEnter *.tex
\ 3match none | unlet! g:loaded_matchparen | au! matchparen
" Enable latex matchparen functionality
autocmd! CursorMoved *.tex call s:highlight_matching_pair(1)
autocmd! CursorMovedI *.tex call s:highlight_matching_pair()
augroup END
endif
endfunction
" }}}1
function! vimtex#motion#find_matching_pair(...) " {{{1
if a:0 > 0
normal! gv
@ -117,6 +168,7 @@ function! vimtex#motion#find_matching_pair(...) " {{{1
endif
endfunction
" }}}1
function! vimtex#motion#next_section(type, backwards, visual) " {{{1
" Restore visual mode if desired
if a:visual
@ -151,6 +203,7 @@ function! vimtex#motion#next_section(type, backwards, visual) " {{{1
endif
endfunction
" }}}1
function! vimtex#motion#sel_delimiter(...) " {{{1
let inner = a:0 > 0
@ -185,6 +238,7 @@ function! vimtex#motion#sel_delimiter(...) " {{{1
endif
endfunction
" }}}1
function! vimtex#motion#sel_environment(...) " {{{1
let inner = a:0 > 0
@ -214,6 +268,7 @@ function! vimtex#motion#sel_environment(...) " {{{1
endif
endfunction
" }}}1
function! vimtex#motion#sel_inline_math(...) " {{{1
let inner = a:0 > 0
@ -245,44 +300,6 @@ function! vimtex#motion#sel_inline_math(...) " {{{1
endfunction
" }}}1
" {{{1 Common patterns
let s:notbslash = '\%(\\\@<!\%(\\\\\)*\)\@<='
let s:notcomment = '\%(\%(\\\@<!\%(\\\\\)*\)\@<=%.*\)\@<!'
" Patterns to match opening and closing delimiters/environments
let s:delimiters_open = [
\ '{',
\ '(',
\ '\[',
\ '\\{',
\ '\\(',
\ '\\\[',
\ '\\\Cbegin\s*{.\{-}}',
\ '\\\Cleft\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\((\|\[\|\\{\)',
\ ]
let s:delimiters_close = [
\ '}',
\ ')',
\ '\]',
\ '\\}',
\ '\\)',
\ '\\\]',
\ '\\\Cend\s*{.\{-}}',
\ '\\\Cright\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\()\|\]\|\\}\)',
\ ]
let s:delimiters = join(s:delimiters_open + s:delimiters_close, '\|')
let s:delimiters = '\(' . s:delimiters . '\|\$\)'
" Pattern to match section/chapter/...
let s:section = s:notcomment . '\v\s*\\'
let s:section.= '((sub)*section|chapter|part|appendix|(front|back|main)matter)'
let s:section.= '>'
" }}}1
function! s:highlight_matching_pair(...) " {{{1
if vimtex#util#in_comment() | return | endif
let hmode = a:0 > 0 ? 1 : 0
@ -349,6 +366,7 @@ function! s:highlight_matching_pair(...) " {{{1
endif
endfunction
" }}}1
function! s:search_and_skip_comments(pat, ...) " {{{1
" Usage: s:search_and_skip_comments(pat, [flags, stopline])
let flags = a:0 >= 1 ? a:1 : ''

View File

@ -4,21 +4,92 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#toc#init(initialized) " {{{1
function! vimtex#toc#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_toc_enabled', 1)
if !g:vimtex_toc_enabled | return | endif
" 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_number_width', 0)
call vimtex#util#set_default('g:vimtex_toc_secnumdepth', 3)
call vimtex#util#set_default('g:vimtex_toc_show_numbers', 1)
call vimtex#util#set_default('g:vimtex_toc_show_preamble', 1)
endfunction
" }}}1
function! vimtex#toc#init_script() " {{{1
if !g:vimtex_toc_enabled | return | endif
" Set some constants
let s:name = 'Table of contents (vimtex)'
"
" Define TOC variables
"
" Define counters
let s:max_level = 0
let s:count_matters = 0
" Define dictionary to keep track of TOC numbers
let s:number = {
\ 'part' : 0,
\ 'chapter' : 0,
\ 'section' : 0,
\ 'subsection' : 0,
\ 'subsubsection' : 0,
\ 'subsubsubsection' : 0,
\ 'current_level' : 0,
\ 'preamble' : 0,
\ 'frontmatter' : 0,
\ 'mainmatter' : 0,
\ 'appendix' : 0,
\ 'backmatter' : 0,
\ }
" Map for section hierarchy
let s:sec_to_value = {
\ '_' : 0,
\ 'subsubsubsection' : 1,
\ 'subsubsection' : 2,
\ 'subsection' : 3,
\ 'section' : 4,
\ 'chapter' : 5,
\ 'part' : 6,
\ }
" Define regular expressions to match document parts
let s:re_input = '\v^\s*\\%(input|include)\s*\{'
let s:re_input_file = s:re_input . '\zs[^\}]+\ze}'
let s:re_sec = '\v^\s*\\%(part|chapter|%(sub)*section)\*?\s*\{'
let s:re_sec_starred = '\v^\s*\\%(part|chapter|%(sub)*section)\*'
let s:re_sec_level = '\v^\s*\\\zs%(part|chapter|%(sub)*section)'
let s:re_sec_title = s:re_sec . '\zs.{-}\ze\}?$'
let s:re_matters = '\v^\s*\\%(front|main|back)matter>'
let s:re_structure = '\v^\s*\\((front|main|back)matter|appendix)>'
let s:re_structure_match = '\v((front|main|back)matter|appendix)'
let s:re_other = {
\ 'toc' : {
\ 'title' : 'Table of contents',
\ 're' : '\v^\s*\\tableofcontents',
\ },
\ 'index' : {
\ 'title' : 'Alphabetical index',
\ 're' : '\v^\s*\\printindex\[?',
\ },
\ 'bib' : {
\ 'title' : 'Bibliography',
\ 're' : '\v^\s*\\%('
\ . 'printbib%(liography|heading)\s*(\{|\[)?'
\ . '|begin\s*\{\s*thebibliography\s*\}'
\ . '|bibliography\s*\{)',
\ },
\ }
endfunction
" }}}1
function! vimtex#toc#init_buffer() " {{{1
if !g:vimtex_toc_enabled | return | endif
" Define commands
command! -buffer VimtexTocOpen call vimtex#toc#open()
command! -buffer VimtexTocToggle call vimtex#toc#toggle()
@ -28,6 +99,8 @@ function! vimtex#toc#init(initialized) " {{{1
nnoremap <buffer> <plug>(vimtex-toc-toggle) :call vimtex#toc#toggle()<cr>
endfunction
" }}}1
function! vimtex#toc#open() " {{{1
if vimtex#index#open(s:name) | return | endif
@ -58,6 +131,7 @@ function! vimtex#toc#open() " {{{1
call vimtex#index#create(index)
endfunction
" }}}1
function! vimtex#toc#toggle() " {{{1
if vimtex#index#open(s:name)
call vimtex#index#close(s:name)
@ -226,67 +300,6 @@ endfunction
" }}}1
" {{{1 TOC variables
let s:max_level = 0
let s:count_matters = 0
" Define dictionary to keep track of TOC numbers
let s:number = {
\ 'part' : 0,
\ 'chapter' : 0,
\ 'section' : 0,
\ 'subsection' : 0,
\ 'subsubsection' : 0,
\ 'subsubsubsection' : 0,
\ 'current_level' : 0,
\ 'preamble' : 0,
\ 'frontmatter' : 0,
\ 'mainmatter' : 0,
\ 'appendix' : 0,
\ 'backmatter' : 0,
\ }
" Map for section hierarchy
let s:sec_to_value = {
\ '_' : 0,
\ 'subsubsubsection' : 1,
\ 'subsubsection' : 2,
\ 'subsection' : 3,
\ 'section' : 4,
\ 'chapter' : 5,
\ 'part' : 6,
\ }
" Define regular expressions to match document parts
let s:re_input = '\v^\s*\\%(input|include)\s*\{'
let s:re_input_file = s:re_input . '\zs[^\}]+\ze}'
let s:re_sec = '\v^\s*\\%(part|chapter|%(sub)*section)\*?\s*\{'
let s:re_sec_starred = '\v^\s*\\%(part|chapter|%(sub)*section)\*'
let s:re_sec_level = '\v^\s*\\\zs%(part|chapter|%(sub)*section)'
let s:re_sec_title = s:re_sec . '\zs.{-}\ze\}?$'
let s:re_matters = '\v^\s*\\%(front|main|back)matter>'
let s:re_structure = '\v^\s*\\((front|main|back)matter|appendix)>'
let s:re_structure_match = '\v((front|main|back)matter|appendix)'
let s:re_other = {
\ 'toc' : {
\ 'title' : 'Table of contents',
\ 're' : '\v^\s*\\tableofcontents',
\ },
\ 'index' : {
\ 'title' : 'Alphabetical index',
\ 're' : '\v^\s*\\printindex\[?',
\ },
\ 'bib' : {
\ 'title' : 'Bibliography',
\ 're' : '\v^\s*\\%('
\ . 'printbib%(liography|heading)\s*(\{|\[)?'
\ . '|begin\s*\{\s*thebibliography\s*\}'
\ . '|bibliography\s*\{)',
\ },
\ }
" }}}1
function! s:parse_toc() " {{{1
let file = b:vimtex.tex
@ -406,6 +419,7 @@ function! s:parse_file(file) " {{{1
return toc
endfunction
" }}}1
function! s:parse_line_input(line, file) " {{{1
let l:file = matchstr(a:line, s:re_input_file)
@ -431,6 +445,7 @@ function! s:parse_line_input(line, file) " {{{1
endif
endfunction
" }}}1
function! s:parse_line_sec(file, lnum, line) " {{{1
let title = matchstr(a:line, s:re_sec_title)
let level = matchstr(a:line, s:re_sec_level)
@ -460,8 +475,8 @@ function! s:number_reset(part) " {{{1
let s:number[a:part] = 1
endfunction
" }}}1
function! s:number_increment(level) " {{{1
" Increment numbers
if a:level ==# 'part'
let s:number.part += 1
let s:number.chapter = 0

View File

@ -4,6 +4,94 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#util#init_options() " {{{1
endfunction
" }}}1
function! vimtex#util#init_script() " {{{1
let s:delimiters_open = [
\ '(',
\ '\[',
\ '\\{',
\ '\\\Cleft\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\((\|\[\|\\{\)',
\ ]
let s:delimiters_close = [
\ ')',
\ '\]',
\ '\\}',
\ '\\\Cright\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\()\|\]\|\\}\)',
\ ]
let s:convert_back_list = map([
\ ['\\''A}' , 'Á'],
\ ['\\`A}' , 'À'],
\ ['\\^A}' , 'À'],
\ ['\\¨A}' , 'Ä'],
\ ['\\"A}' , 'Ä'],
\ ['\\''a}' , 'á'],
\ ['\\`a}' , 'à'],
\ ['\\^a}' , 'à'],
\ ['\\¨a}' , 'ä'],
\ ['\\"a}' , 'ä'],
\ ['\\''E}' , 'É'],
\ ['\\`E}' , 'È'],
\ ['\\^E}' , 'Ê'],
\ ['\\¨E}' , 'Ë'],
\ ['\\"E}' , 'Ë'],
\ ['\\''e}' , 'é'],
\ ['\\`e}' , 'è'],
\ ['\\^e}' , 'ê'],
\ ['\\¨e}' , 'ë'],
\ ['\\"e}' , 'ë'],
\ ['\\''I}' , 'Í'],
\ ['\\`I}' , 'Î'],
\ ['\\^I}' , 'Ì'],
\ ['\\¨I}' , 'Ï'],
\ ['\\"I}' , 'Ï'],
\ ['\\''i}' , 'í'],
\ ['\\`i}' , 'î'],
\ ['\\^i}' , 'ì'],
\ ['\\¨i}' , 'ï'],
\ ['\\"i}' , 'ï'],
\ ['\\''{\?\\i }' , 'í'],
\ ['\\''O}' , 'Ó'],
\ ['\\`O}' , 'Ò'],
\ ['\\^O}' , 'Ô'],
\ ['\\¨O}' , 'Ö'],
\ ['\\"O}' , 'Ö'],
\ ['\\''o}' , 'ó'],
\ ['\\`o}' , 'ò'],
\ ['\\^o}' , 'ô'],
\ ['\\¨o}' , 'ö'],
\ ['\\"o}' , 'ö'],
\ ['\\o }' , 'ø'],
\ ['\\''U}' , 'Ú'],
\ ['\\`U}' , 'Ù'],
\ ['\\^U}' , 'Û'],
\ ['\\¨U}' , 'Ü'],
\ ['\\"U}' , 'Ü'],
\ ['\\''u}' , 'ú'],
\ ['\\`u}' , 'ù'],
\ ['\\^u}' , 'û'],
\ ['\\¨u}' , 'ü'],
\ ['\\"u}' , 'ü'],
\ ['\\`N}' , 'Ǹ'],
\ ['\\\~N}' , 'Ñ'],
\ ['\\''n}' , 'ń'],
\ ['\\`n}' , 'ǹ'],
\ ['\\\~n}' , 'ñ'],
\], '[''\C\(\\IeC\s*{\)\?'' . v:val[0], v:val[1]]')
endfunction
" }}}1
function! vimtex#util#init_buffer() " {{{1
endfunction
" }}}1
function! vimtex#util#convert_back(line) " {{{1
"
" Substitute stuff like '\IeC{\"u}' to corresponding unicode symbols
@ -20,74 +108,7 @@ function! vimtex#util#convert_back(line) " {{{1
return substitute(line, '\C\(\\IeC\s*{\)\?\\.\(.\)}', '\1', 'g')
endfunction
let s:convert_back_list = map([
\ ['\\''A}' , 'Á'],
\ ['\\`A}' , 'À'],
\ ['\\^A}' , 'À'],
\ ['\\¨A}' , 'Ä'],
\ ['\\"A}' , 'Ä'],
\ ['\\''a}' , 'á'],
\ ['\\`a}' , 'à'],
\ ['\\^a}' , 'à'],
\ ['\\¨a}' , 'ä'],
\ ['\\"a}' , 'ä'],
\ ['\\''E}' , 'É'],
\ ['\\`E}' , 'È'],
\ ['\\^E}' , 'Ê'],
\ ['\\¨E}' , 'Ë'],
\ ['\\"E}' , 'Ë'],
\ ['\\''e}' , 'é'],
\ ['\\`e}' , 'è'],
\ ['\\^e}' , 'ê'],
\ ['\\¨e}' , 'ë'],
\ ['\\"e}' , 'ë'],
\ ['\\''I}' , 'Í'],
\ ['\\`I}' , 'Î'],
\ ['\\^I}' , 'Ì'],
\ ['\\¨I}' , 'Ï'],
\ ['\\"I}' , 'Ï'],
\ ['\\''i}' , 'í'],
\ ['\\`i}' , 'î'],
\ ['\\^i}' , 'ì'],
\ ['\\¨i}' , 'ï'],
\ ['\\"i}' , 'ï'],
\ ['\\''{\?\\i }' , 'í'],
\ ['\\''O}' , 'Ó'],
\ ['\\`O}' , 'Ò'],
\ ['\\^O}' , 'Ô'],
\ ['\\¨O}' , 'Ö'],
\ ['\\"O}' , 'Ö'],
\ ['\\''o}' , 'ó'],
\ ['\\`o}' , 'ò'],
\ ['\\^o}' , 'ô'],
\ ['\\¨o}' , 'ö'],
\ ['\\"o}' , 'ö'],
\ ['\\o }' , 'ø'],
\ ['\\''U}' , 'Ú'],
\ ['\\`U}' , 'Ù'],
\ ['\\^U}' , 'Û'],
\ ['\\¨U}' , 'Ü'],
\ ['\\"U}' , 'Ü'],
\ ['\\''u}' , 'ú'],
\ ['\\`u}' , 'ù'],
\ ['\\^u}' , 'û'],
\ ['\\¨u}' , 'ü'],
\ ['\\"u}' , 'ü'],
\ ['\\`N}' , 'Ǹ'],
\ ['\\\~N}' , 'Ñ'],
\ ['\\''n}' , 'ń'],
\ ['\\`n}' , 'ǹ'],
\ ['\\\~n}' , 'ñ'],
\], '[''\C\(\\IeC\s*{\)\?'' . v:val[0], v:val[1]]')
function! vimtex#util#error_deprecated(variable) " {{{1
if exists(a:variable)
echoerr "Deprecation error: " . a:variable
echoerr "Please read docs for more info!"
echoerr ":h vimtex-changelog"
endif
endfunction
" }}}1
function! vimtex#util#execute(exe) " {{{1
" Execute the given command on the current system. Wrapper function to make
" it easier to run on both windows and unix.
@ -106,8 +127,8 @@ function! vimtex#util#execute(exe) " {{{1
" Check and parse arguments
if !has_key(a:exe, 'cmd')
echoerr "Error in vimtex#util#execute!"
echoerr "Argument error, exe.cmd does not exist!"
echoerr 'Error in vimtex#util#execute!'
echoerr 'Argument error, exe.cmd does not exist!'
return
endif
let bg = has_key(a:exe, 'bg') ? a:exe.bg : 1
@ -159,7 +180,7 @@ function! vimtex#util#execute(exe) " {{{1
execute '!' . cmd
endif
if !has("gui_running")
if !has('gui_running')
redraw!
endif
endif
@ -175,6 +196,7 @@ function! vimtex#util#execute(exe) " {{{1
endif
endfunction
" }}}1
function! vimtex#util#fnameescape(path) " {{{1
"
" In a Windows environment, a path used in "cmd" only needs to be enclosed by
@ -186,6 +208,7 @@ function! vimtex#util#fnameescape(path) " {{{1
return has('win32') ? '"' . a:path . '"' : shellescape(a:path)
endfunction
" }}}1
function! vimtex#util#get_env(...) " {{{1
" vimtex#util#get_env([with_pos])
" Returns:
@ -202,7 +225,7 @@ function! vimtex#util#get_env(...) " {{{1
" move to the left until on a backslash
let [bufnum, lnum, cnum, off] = getpos('.')
let line = getline(lnum)
while cnum > 1 && line[cnum - 1] != '\'
while cnum > 1 && line[cnum - 1] !=# '\'
let cnum -= 1
endwhile
call cursor(lnum, cnum)
@ -248,6 +271,7 @@ function! vimtex#util#get_env(...) " {{{1
endif
endfunction
" }}}1
function! vimtex#util#get_delim() " {{{1
" Save position in order to restore before finishing
let pos_original = getpos('.')
@ -307,33 +331,20 @@ function! vimtex#util#get_delim() " {{{1
return [d1,l1,c1,d2,l2,c2]
endfunction
let s:delimiters_open = [
\ '(',
\ '\[',
\ '\\{',
\ '\\\Cleft\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\((\|\[\|\\{\)',
\ ]
let s:delimiters_close = [
\ ')',
\ '\]',
\ '\\}',
\ '\\\Cright\s*\%([^\\a-zA-Z0-9]\|\\.\|\\\a*\)',
\ '\\\cbigg\?\()\|\]\|\\}\)',
\ ]
" }}}1
function! vimtex#util#get_os() " {{{1
if has("win32")
return "win"
elseif has("unix")
if system('uname') =~ 'Darwin'
return "mac"
if has('win32')
return 'win'
elseif has('unix')
if system('uname') =~# 'Darwin'
return 'mac'
else
return "linux"
return 'linux'
endif
endif
endfunction
" }}}1
function! vimtex#util#has_syntax(name, ...) " {{{1
" Usage: vimtex#util#has_syntax(name, [line], [col])
let line = a:0 >= 1 ? a:1 : line('.')
@ -342,10 +353,12 @@ function! vimtex#util#has_syntax(name, ...) " {{{1
\ 'synIDattr(v:val, "name") == "' . a:name . '"'), 1)
endfunction
" }}}1
function! vimtex#util#in_comment(...) " {{{1
return synIDattr(synID(line('.'), col('.'), 0), "name") =~# '^texComment'
return synIDattr(synID(line('.'), col('.'), 0), 'name') =~# '^texComment'
endfunction
" }}}1
function! vimtex#util#kpsewhich(file, ...) " {{{1
let cmd = 'kpsewhich '
let cmd .= a:0 > 0 ? a:1 : ''
@ -362,57 +375,20 @@ function! vimtex#util#kpsewhich(file, ...) " {{{1
return out
endfunction
" }}}1
function! vimtex#util#set_default(variable, default) " {{{1
if !exists(a:variable)
let {a:variable} = a:default
endif
endfunction
" }}}1
function! vimtex#util#set_default_os_specific(variable, default) " {{{1
if !exists(a:variable)
let {a:variable} = get(a:default, vimtex#util#get_os(), '')
endif
endfunction
function! vimtex#util#tex2tree(str) " {{{1
let tree = []
let i1 = 0
let i2 = -1
let depth = 0
while i2 < len(a:str)
let i2 = match(a:str, '[{}]', i2 + 1)
if i2 < 0
let i2 = len(a:str)
endif
if i2 >= len(a:str) || a:str[i2] == '{'
if depth == 0
let item = substitute(strpart(a:str, i1, i2 - i1),
\ '^\s*\|\s*$', '', 'g')
if !empty(item)
call add(tree, item)
endif
let i1 = i2 + 1
endif
let depth += 1
else
let depth -= 1
if depth == 0
call add(tree, vimtex#util#tex2tree(strpart(a:str, i1, i2 - i1)))
let i1 = i2 + 1
endif
endif
endwhile
return tree
endfunction
function! vimtex#util#tree2tex(tree) " {{{1
if type(a:tree) == type('')
return a:tree
else
return '{' . join(map(a:tree, 'vimtex#util#tree2tex(v:val)'), '') . '}'
endif
endfunction
" }}}1
" vim: fdm=marker sw=2

View File

@ -4,53 +4,6 @@
" Email: karl.yngve@gmail.com
"
function! vimtex#view#init(initialized) " {{{1
call vimtex#util#set_default('g:vimtex_view_enabled', 1)
if !g:vimtex_view_enabled | return | endif
" Initialize viewer options
for viewer in s:viewers
call vimtex#util#set_default('g:vimtex_view_' . viewer . '_options', '')
endfor
" Initialize other options
call vimtex#util#set_default_os_specific('g:vimtex_view_general_viewer',
\ {
\ 'linux' : 'xdg-open',
\ 'mac' : 'open',
\ })
call vimtex#util#set_default('g:vimtex_view_method', 'general')
call vimtex#util#set_default('g:vimtex_view_mupdf_send_keys', '')
call vimtex#util#error_deprecated('g:vimtex_viewer')
let viewer = 's:' . g:vimtex_view_method
if !exists(viewer)
echoerr 'vimtex viewer ' . g:vimtex_view_method . ' does not exist!'
return
endif
execute 'let b:vimtex.viewer = ' . viewer
call b:vimtex.viewer.init()
" Define commands
command! -buffer -nargs=? -complete=file VimtexView
\ call b:vimtex.viewer.view(<q-args>)
if has_key(b:vimtex.viewer, 'reverse_search')
command! -buffer -nargs=* VimtexRSearch
\ call b:vimtex.viewer.reverse_search()
endif
" Define mappings
nnoremap <buffer> <plug>(vimtex-view)
\ :call b:vimtex.viewer.view('')<cr>
if has_key(b:vimtex.viewer, 'reverse_search')
nnoremap <buffer> <plug>(vimtex-reverse-search)
\ :call b:vimtex.viewer.reverse_search()<cr>
endif
endfunction
" }}}1
let s:viewers = [
\ 'general',
\ 'mupdf',
@ -63,6 +16,68 @@ for viewer in s:viewers
execute 'let s:' . viewer . ' = {}'
endfor
function! vimtex#view#init_options() " {{{1
call vimtex#util#set_default('g:vimtex_view_enabled', 1)
if !g:vimtex_view_enabled | return | endif
for viewer in s:viewers
call vimtex#util#set_default('g:vimtex_view_' . viewer . '_options', '')
endfor
call vimtex#util#set_default_os_specific('g:vimtex_view_general_viewer',
\ {
\ 'linux' : 'xdg-open',
\ 'mac' : 'open',
\ })
call vimtex#util#set_default('g:vimtex_view_method', 'general')
call vimtex#util#set_default('g:vimtex_view_mupdf_send_keys', '')
endfunction
" }}}1
function! vimtex#view#init_script() " {{{1
endfunction
" }}}1
function! vimtex#view#init_buffer() " {{{1
if !g:vimtex_view_enabled | return | endif
"
" Add viewer to the data blob
"
let viewer = 's:' . g:vimtex_view_method
if !exists(viewer)
echoerr 'vimtex viewer ' . g:vimtex_view_method . ' does not exist!'
return
endif
execute 'let b:vimtex.viewer = ' . viewer
call b:vimtex.viewer.init()
"
" Define commands
"
command! -buffer -nargs=? -complete=file VimtexView
\ call b:vimtex.viewer.view(<q-args>)
if has_key(b:vimtex.viewer, 'reverse_search')
command! -buffer -nargs=* VimtexRSearch
\ call b:vimtex.viewer.reverse_search()
endif
"
" Define mappings
"
nnoremap <buffer> <plug>(vimtex-view)
\ :call b:vimtex.viewer.view('')<cr>
if has_key(b:vimtex.viewer, 'reverse_search')
nnoremap <buffer> <plug>(vimtex-reverse-search)
\ :call b:vimtex.viewer.reverse_search()<cr>
endif
endfunction
" }}}1
"
" Define viewers
"
" {{{1 General
function! s:general.init() dict " {{{2
if !executable(g:vimtex_view_general_viewer)
@ -391,9 +406,10 @@ endfunction
" }}}2
" }}}1
" {{{1 Common functionality
function! s:output_not_readable(output) " {{{2
"
" Common functionality
"
function! s:output_not_readable(output) " {{{1
if !filereadable(a:output)
call vimtex#echo#warning('vimtex viewer can not read PDF file!')
return 1
@ -402,8 +418,8 @@ function! s:output_not_readable(output) " {{{2
endif
endfunction
" }}}2
function! s:xwin_get_id() dict " {{{2
" }}}1
function! s:xwin_get_id() dict " {{{1
if !executable('xdotool') | return 0 | endif
if self.xwin_id > 0 | return 0 | endif
sleep 500m
@ -421,8 +437,8 @@ function! s:xwin_get_id() dict " {{{2
return self.xwin_id
endfunction
" }}}2
function! s:xwin_exists() dict " {{{2
" }}}1
function! s:xwin_exists() dict " {{{1
if !executable('xdotool') | return 0 | endif
let cmd = 'xdotool search --class ' . self.class
@ -437,8 +453,8 @@ function! s:xwin_exists() dict " {{{2
return 0
endfunction
" }}}2
function! s:xwin_send_keys(keys) dict " {{{2
" }}}1
function! s:xwin_send_keys(keys) dict " {{{1
if !executable('xdotool') | return | endif
if a:keys !=# ''
@ -448,8 +464,8 @@ function! s:xwin_send_keys(keys) dict " {{{2
endif
endfunction
" }}}2
function! s:focus_viewer() dict " {{{2
" }}}1
function! s:focus_viewer() dict " {{{1
if !executable('xdotool') | return | endif
if self.xwin_exists()
@ -458,15 +474,14 @@ function! s:focus_viewer() dict " {{{2
endif
endfunction
function! s:focus_vim() dict " {{{2
" }}}1
function! s:focus_vim() dict " {{{1
if !executable('xdotool') | return | endif
silent execute '!xdotool windowfocus ' . v:windowid
redraw!
endfunction
" }}}2
" }}}1
" vim: fdm=marker sw=2

View File

@ -1270,6 +1270,20 @@ The following changelog only logs particularly important changes, such as
changes that break backwards compatibility. See the git log for the detailed
changelog.
2015-06-06: Minor but convenient restructuring (++)~
I've changed a lot of the code structure in relatively small ways. For
instance, instead of referring to the particular data blobs through the global
array, I instead linked a buffer variable to the correct global array element.
One particular change is that all modules are now initialized in three steps:
1. Initialize module options
2. Initialize script variables and single execution functionalities
3. Initialize buffer options
Finally, I've cleaned up a lot of the code by removing some deprecation
warnings and similar.
2015-03-21: Implemented index buffers, deprecated vimtex_toc filetype~
The system for displaying the table of content relied on a dedicated filetype
plugin. This was inherited from LaTeX-Box, and worked quite well. However,