vimtex/autoload/vimtex.vim

834 lines
22 KiB
VimL
Raw Normal View History

2015-03-07 17:02:15 -05:00
" vimtex - LaTeX plugin for Vim
2014-07-22 18:08:57 -04:00
"
" Maintainer: Karl Yngve Lervåg
" Email: karl.yngve@gmail.com
"
" {{{1 Script Initialization
2015-06-06 17:49:28 -04:00
"
" 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.
"
2015-03-23 14:18:19 -04:00
if !exists('s:initialized')
let s:initialized = 0
endif
2015-06-06 17:49:28 -04:00
"
" 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
2013-10-05 07:53:42 -04:00
2015-06-06 17:49:28 -04:00
" }}}1
2013-10-05 07:53:42 -04:00
2015-06-06 17:49:28 -04:00
function! vimtex#init() " {{{1
2015-11-10 17:26:24 -05:00
call s:check_version()
2013-10-05 07:53:42 -04:00
"
2015-06-06 17:49:28 -04:00
" First initialize buffer options and construct (if necessary) the vimtex
" data blob.
2013-10-05 07:53:42 -04:00
"
try
call s:init_buffer()
catch '^vimtex'
return
endtry
2013-10-05 07:53:42 -04:00
2015-06-06 17:49:28 -04:00
"
" 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
2015-06-06 17:49:28 -04:00
call s:init_modules('options')
call s:init_modules('script')
2015-06-05 17:55:34 -04:00
endif
2015-06-06 17:49:28 -04:00
call s:init_modules('buffer')
2013-10-05 07:53:42 -04:00
"
" Initialize local blob (if main file is different then current file)
"
call s:init_local_blob()
2015-11-06 17:51:39 -05:00
"
" Finally we create the mappings
"
call s:init_mappings()
let s:initialized = 1
"
" Allow custom configuration through an event hook
"
2015-11-10 04:35:12 -05:00
if exists('#User#VimtexEventInitPost')
doautocmd User VimtexEventInitPost
endif
2015-05-16 16:14:52 -04:00
endfunction
2013-10-05 07:53:42 -04:00
" }}}1
2015-11-10 17:38:56 -05:00
function! vimtex#info(global) " {{{1
if !s:initialized
echoerr 'Error: vimtex has not been initialized!'
return
endif
if a:global
for [id, data] in items(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([
\ "\ng:vimtex_data[", ['VimtexSuccess', id], '] : ',
\ ['VimtexSuccess', remove(d, 'name') . "\n"]])
call s:print_dict(d)
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#wc(detailed, ...) " {{{1
2015-11-10 17:38:56 -05:00
" Run texcount, save output to lines variable
let cmd = 'cd ' . vimtex#util#shellescape(b:vimtex.root)
let cmd .= '; texcount -nosub -sum '
let cmd .= a:0 > 0 ? '-letter ' : ''
2015-11-10 17:38:56 -05:00
let cmd .= a:detailed > 0 ? '-inc ' : '-merge '
let cmd .= vimtex#util#shellescape(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 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
" {{{1 function! vimtex#reload()
let s:file = expand('<sfile>')
2016-07-28 08:01:37 -04:00
if get(s:, 'reload_guard', 1)
function! vimtex#reload()
2016-07-28 08:01:37 -04:00
let s:reload_guard = 0
let l:scripts = [s:file]
\ + map(copy(s:modules),
\ 'fnamemodify(s:file, '':h'') . ''/vimtex/'' . v:val . ''.vim''')
for l:file in l:scripts
execute 'source' l:file
endfor
let s:initialized = 0
call vimtex#init()
2016-02-23 15:03:53 -05:00
" Reload indent file
if exists('b:did_vimtex_indent')
unlet b:did_indent
runtime indent/tex.vim
endif
call vimtex#echo#info('reloaded')
2016-07-28 08:01:37 -04:00
unlet s:reload_guard
endfunction
endif
" }}}1
function! vimtex#toggle_main() " {{{1
if exists('b:vimtex_local')
let b:vimtex_local.active = !b:vimtex_local.active
let b:vimtex_id = b:vimtex_local.active
\ ? b:vimtex_local.sub_id
\ : b:vimtex_local.main_id
let b:vimtex = g:vimtex_data[b:vimtex_id]
call vimtex#echo#status(['vimtex: ',
\ ['Normal', 'Changed to `'],
\ ['VimtexSuccess', b:vimtex.base],
\ ['Normal', "' "],
\ ['VimtexInfo', b:vimtex_local.active ? '[local]' : '[main]' ]])
endif
endfunction
2015-11-10 17:38:56 -05:00
" }}}1
2013-10-05 07:53:42 -04:00
2015-11-10 17:26:24 -05:00
function! s:check_version() " {{{1
if s:initialized || get(g:, 'vimtex_disable_version_warning', 0)
return
endif
if v:version <= 703 && !has('patch544')
echoerr 'vimtex error: Please use Vim version 7.3.544 or newer!'
endif
2015-11-10 17:26:24 -05:00
endfunction
" }}}1
2015-11-10 17:38:56 -05:00
2015-06-06 17:49:28 -04:00
function! s:init_buffer() " {{{1
"
" First we set some vim options
"
2015-04-01 09:54:14 -04:00
let s:save_cpo = &cpo
set cpo&vim
" Ensure tex files are prioritized when listing files
for suf in [
\ '.log',
\ '.aux',
\ '.bbl',
\ '.out',
\ '.blg',
\ '.brf',
\ '.cb',
\ '.dvi',
\ '.fdb_latexmk',
\ '.fls',
\ '.idx',
\ '.ilg',
\ '.ind',
\ '.inx',
\ '.pdf',
\ '.synctex.gz',
\ '.toc',
\ ]
execute 'set suffixes+=' . suf
endfor
setlocal suffixesadd=.tex
setlocal comments=sO:%\ -,mO:%\ \ ,eO:%%,:%
setlocal commentstring=%%s
let &l:define = '\\\([egx]\|char\|mathchar\|count\|dimen\|muskip\|skip'
let &l:define .= '\|toks\)\=def\|\\font\|\\\(future\)\=let'
let &l:define .= '\|\\new\(count\|dimen\|skip'
let &l:define .= '\|muskip\|box\|toks\|read\|write\|fam\|insert\)'
let &l:define .= '\|\\\(re\)\=new\(boolean\|command\|counter\|environment'
let &l:define .= '\|font\|if\|length\|savebox'
let &l:define .= '\|theorem\(style\)\=\)\s*\*\=\s*{\='
let &l:define .= '\|DeclareMathOperator\s*{\=\s*'
2016-02-16 16:35:09 -05:00
let &l:include = '\v\\%(input|include)\{'
2015-04-01 09:57:02 -04:00
let &l:includeexpr = 'substitute('
let &l:includeexpr .= "substitute(v:fname, '\\\\space', '', 'g'),"
let &l:includeexpr .= "'^.\\{-}{\"\\?\\|\"\\?}.*', '', 'g')"
2015-04-01 09:54:14 -04:00
let &cpo = s:save_cpo
unlet s:save_cpo
2015-06-06 17:49:28 -04:00
"
" Next we initialize the data blob
"
" Create container for data blobs if it does not exist
2015-11-10 04:35:12 -05:00
let g:vimtex_data = get(g:, 'vimtex_data', {})
2015-06-06 17:49:28 -04:00
" 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
2015-11-10 13:33:40 -05:00
let b:vimtex = g:vimtex_data[id]
2015-06-06 17:49:28 -04:00
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')
2016-08-04 16:12:18 -04:00
let b:vimtex.aux = function('s:get_aux')
let b:vimtex.log = function('s:get_log')
let b:vimtex.out = function('s:get_out')
let b:vimtex.ext = function('s:get_ext')
2015-06-06 17:49:28 -04:00
2015-11-10 04:35:12 -05:00
let s:vimtex_next_id = get(s:, 'vimtex_next_id', -1) + 1
let b:vimtex_id = s:vimtex_next_id
let g:vimtex_data[b:vimtex_id] = b:vimtex
2015-06-06 17:49:28 -04:00
endif
"
2015-06-20 17:16:53 -04:00
" Define commands and mappings
2015-06-06 17:49:28 -04:00
"
" Define commands
command! -buffer -bang VimtexInfo call vimtex#info(<q-bang> == "!")
command! -buffer -bang VimtexCountWords call vimtex#wc(<q-bang> == "!")
command! -buffer -bang VimtexCountLetters call vimtex#wc(<q-bang> == "!", 1)
command! -buffer VimtexReload call vimtex#reload()
command! -buffer VimtexToggleMain call vimtex#toggle_main()
2015-06-06 17:49:28 -04:00
" Define mappings
nnoremap <buffer> <plug>(vimtex-info) :VimtexInfo<cr>
nnoremap <buffer> <plug>(vimtex-info-full) :VimtexInfo!<cr>
nnoremap <buffer> <plug>(vimtex-reload) :VimtexReload<cr>
nnoremap <buffer> <plug>(vimtex-toggle-main) :VimtexToggleMain<cr>
2015-06-20 17:16:53 -04:00
"
" Attach autocommands
"
augroup vimtex_buffers
2015-06-20 17:16:53 -04:00
au BufFilePre <buffer> call s:filename_changed_pre()
au BufFilePost <buffer> call s:filename_changed_post()
au BufLeave <buffer> call s:buffer_left()
au BufDelete <buffer> call s:buffer_deleted()
au QuitPre <buffer> call s:buffer_deleted(b:vimtex_id)
2015-06-20 17:16:53 -04:00
augroup END
2015-06-06 17:49:28 -04:00
endfunction
" }}}1
function! s:init_mappings() " {{{1
if !get(g:,'vimtex_mappings_enabled', 1) | return | endif
function! s:map(mode, lhs, rhs, ...)
2016-06-28 09:13:51 -04:00
if (a:0 > 0) || (maparg(a:lhs, a:mode) ==# '')
silent execute a:mode . 'map <silent><buffer>' a:lhs a:rhs
endif
endfunction
call s:map('n', '<localleader>li', '<plug>(vimtex-info)')
call s:map('n', '<localleader>lI', '<plug>(vimtex-info-full)')
call s:map('n', '<localleader>lx', '<plug>(vimtex-reload)')
call s:map('n', '<localleader>ls', '<plug>(vimtex-toggle-main)')
call s:map('n', 'ds$', '<plug>(vimtex-env-delete-math)')
call s:map('n', 'cs$', '<plug>(vimtex-env-change-math)')
call s:map('n', 'dse', '<plug>(vimtex-env-delete)')
call s:map('n', 'cse', '<plug>(vimtex-env-change)')
call s:map('n', 'tse', '<plug>(vimtex-env-toggle-star)')
call s:map('n', 'dsc', '<plug>(vimtex-cmd-delete)')
call s:map('n', 'csc', '<plug>(vimtex-cmd-change)')
call s:map('n', '<F7>', '<plug>(vimtex-cmd-create)')
call s:map('i', '<F7>', '<plug>(vimtex-cmd-create)')
call s:map('n', 'tsd', '<plug>(vimtex-delim-toggle-modifier)')
2016-03-22 03:34:26 -04:00
call s:map('v', 'tsd', '<plug>(vimtex-delim-toggle-modifier)')
call s:map('i', ']]', '<plug>(vimtex-delim-close)')
if g:vimtex_latexmk_enabled
call s:map('n', '<localleader>ll', '<plug>(vimtex-compile-toggle)')
call s:map('n', '<localleader>lo', '<plug>(vimtex-compile-output)')
call s:map('n', '<localleader>lL', '<plug>(vimtex-compile-selected)')
call s:map('x', '<localleader>lL', '<plug>(vimtex-compile-selected)')
call s:map('n', '<localleader>lk', '<plug>(vimtex-stop)')
call s:map('n', '<localleader>lK', '<plug>(vimtex-stop-all)')
call s:map('n', '<localleader>le', '<plug>(vimtex-errors)')
call s:map('n', '<localleader>lc', '<plug>(vimtex-clean)')
call s:map('n', '<localleader>lC', '<plug>(vimtex-clean-full)')
call s:map('n', '<localleader>lg', '<plug>(vimtex-status)')
call s:map('n', '<localleader>lG', '<plug>(vimtex-status-all)')
endif
if g:vimtex_motion_enabled
call s:map('n', ']]', '<plug>(vimtex-]])')
call s:map('n', '][', '<plug>(vimtex-][)')
call s:map('n', '[]', '<plug>(vimtex-[])')
call s:map('n', '[[', '<plug>(vimtex-[[)')
call s:map('x', ']]', '<plug>(vimtex-]])')
call s:map('x', '][', '<plug>(vimtex-][)')
call s:map('x', '[]', '<plug>(vimtex-[])')
call s:map('x', '[[', '<plug>(vimtex-[[)')
call s:map('o', ']]', '<plug>(vimtex-]])')
call s:map('o', '][', '<plug>(vimtex-][)')
call s:map('o', '[]', '<plug>(vimtex-[])')
call s:map('o', '[[', '<plug>(vimtex-[[)')
" These are forced in order to overwrite matchit mappings
call s:map('n', '%', '<plug>(vimtex-%)', 1)
call s:map('x', '%', '<plug>(vimtex-%)', 1)
call s:map('o', '%', '<plug>(vimtex-%)', 1)
endif
if g:vimtex_text_obj_enabled
2016-02-13 05:39:18 -05:00
call s:map('x', 'ic', '<plug>(vimtex-ic)')
call s:map('x', 'ac', '<plug>(vimtex-ac)')
call s:map('o', 'ic', '<plug>(vimtex-ic)')
call s:map('o', 'ac', '<plug>(vimtex-ac)')
call s:map('x', 'id', '<plug>(vimtex-id)')
call s:map('x', 'ad', '<plug>(vimtex-ad)')
call s:map('o', 'id', '<plug>(vimtex-id)')
call s:map('o', 'ad', '<plug>(vimtex-ad)')
call s:map('x', 'ie', '<plug>(vimtex-ie)')
call s:map('x', 'ae', '<plug>(vimtex-ae)')
call s:map('o', 'ie', '<plug>(vimtex-ie)')
call s:map('o', 'ae', '<plug>(vimtex-ae)')
call s:map('x', 'i$', '<plug>(vimtex-i$)')
call s:map('x', 'a$', '<plug>(vimtex-a$)')
call s:map('o', 'i$', '<plug>(vimtex-i$)')
call s:map('o', 'a$', '<plug>(vimtex-a$)')
endif
if g:vimtex_toc_enabled
call s:map('n', '<localleader>lt', '<plug>(vimtex-toc-open)')
call s:map('n', '<localleader>lT', '<plug>(vimtex-toc-toggle)')
endif
if g:vimtex_labels_enabled
call s:map('n', '<localleader>ly', '<plug>(vimtex-labels-open)')
call s:map('n', '<localleader>lY', '<plug>(vimtex-labels-toggle)')
endif
if g:vimtex_view_enabled
call s:map('n', '<localleader>lv', '<plug>(vimtex-view)')
if has_key(b:vimtex.viewer, 'reverse_search')
call s:map('n', '<localleader>lr', '<plug>(vimtex-reverse-search)')
endif
endif
if g:vimtex_imaps_enabled
call s:map('n', '<localleader>lm', '<plug>(vimtex-imaps-list)')
endif
endfunction
2015-06-06 17:49:28 -04:00
" }}}1
function! s:init_modules(initmode) " {{{1
for module in s:modules
2016-05-15 05:22:43 -04:00
try
execute 'call vimtex#' . module . '#init_' . a:initmode . '()'
catch /E117.*#init_/
endtry
2015-06-06 17:49:28 -04:00
endfor
2014-07-16 17:08:00 -04:00
endfunction
2015-04-01 09:54:14 -04:00
" }}}1
function! s:init_local_blob() " {{{1
let l:filename = expand('%:p')
if b:vimtex.tex !=# l:filename
let l:local = deepcopy(b:vimtex)
let l:local.tex = l:filename
let l:local.pid = 0
let l:local.name = fnamemodify(l:filename, ':t:r')
let l:local.root = fnamemodify(l:filename, ':h')
let l:local.base = fnamemodify(l:filename, ':t')
let s:vimtex_next_id += 1
let g:vimtex_data[s:vimtex_next_id] = l:local
let b:vimtex_local = {
\ 'active' : 0,
\ 'main_id' : b:vimtex_id,
\ 'sub_id' : s:vimtex_next_id,
\}
endif
endfunction
2014-07-16 17:08:00 -04:00
" }}}1
2013-10-05 07:53:42 -04:00
function! s:get_id(main) " {{{1
2015-11-10 04:35:12 -05:00
for [id, data] in items(g:vimtex_data)
if data.tex == a:main
return str2nr(id)
2015-11-10 04:35:12 -05:00
endif
endfor
2013-10-05 07:53:42 -04:00
return -1
endfunction
function! s:get_main() " {{{1
"
" Check if the current file is a main file
"
if s:file_is_main(expand('%:p'))
return expand('%:p')
endif
"
" Use buffer variable if it exists
"
if exists('b:vimtex_main') && filereadable(b:vimtex_main)
return fnamemodify(b:vimtex_main, ':p')
endif
"
2016-01-13 17:31:59 -05:00
" Search for TEX root specifier at the beginning of file. This is used by
" several other plugins and editors.
"
2016-01-13 17:31:59 -05:00
let l:candidate = s:get_main_from_specifier(
\ '^\c\s*%\s*!\?\s*tex\s\+root\s*=\s*\zs.*\ze\s*$')
if !empty(l:candidate)
2016-01-13 17:31:59 -05:00
return l:candidate
endif
"
2016-01-13 17:31:59 -05:00
" Support for subfiles package
"
let l:candidate = s:get_main_from_specifier(
\ '^\C\s*\\documentclass\[\zs.*\ze\]{subfiles}')
if !empty(l:candidate)
2016-01-13 17:31:59 -05:00
return l:candidate
endif
"
" Search for .latexmain-specifier
"
2016-01-13 17:31:59 -05:00
let l:candidate = s:get_main_latexmain(expand('%:p'))
if !empty(l:candidate)
2016-01-13 17:31:59 -05:00
return l:candidate
endif
"
" Check if we are class or style file
"
if index(['cls', 'sty'], expand('%:e')) >= 0
let id = getbufvar('#', 'vimtex_id', -1)
if id >= 0
return g:vimtex_data[id].tex
else
throw 'vimtex: not valid tex file'
endif
endif
"
" Search for main file recursively through include specifiers
"
let l:candidate = s:get_main_recurse()
2016-01-13 17:31:59 -05:00
if l:candidate !=# ''
return l:candidate
endif
"
" Fallback to the current file
"
return expand('%:p')
endfunction
2016-01-13 17:31:59 -05:00
" }}}1
function! s:get_main_from_specifier(spec) " {{{1
for l:line in getline(1, 5)
let l:filename = matchstr(l:line, a:spec)
if len(l:filename) > 0
if l:filename[0] ==# '/'
if filereadable(l:filename) | return l:filename | endif
else
2016-06-22 16:31:42 -04:00
" The candidate may be relative both to the current buffer file and to
" the working directory (for subfile package)
for l:candidate in map([
\ expand('%:p:h'),
\ getcwd()],
\ 'simplify(v:val . ''/'' . l:filename)')
2016-01-13 17:31:59 -05:00
if filereadable(l:candidate) | return l:candidate | endif
endfor
endif
endif
endfor
return ''
endfunction
2015-06-20 17:16:53 -04:00
" }}}1
function! s:get_main_latexmain(file) " {{{1
"
" Gather candidate files
"
let l:path = expand('%:p:h')
let l:dirs = l:path
while l:path != fnamemodify(l:path, ':h')
let l:path = fnamemodify(l:path, ':h')
let l:dirs .= ',' . l:path
endwhile
let l:candidates = split(globpath(fnameescape(l:dirs), '*.latexmain'), '\n')
2013-12-26 06:19:53 -05:00
"
" Use first valid candidate
2013-12-26 06:19:53 -05:00
"
for l:cand in l:candidates
let l:cand = fnamemodify(l:cand, ':p:r')
if s:file_reaches_current(l:cand)
return l:cand
endif
endfor
return ''
endfunction
function! s:get_main_recurse(...) " {{{1
"
" Either start the search from the original file, or check if the supplied
" file is a main file (or invalid)
"
if a:0 == 0
let l:file = expand('%:p')
else
let l:file = a:1
if s:file_is_main(l:file)
return l:file
elseif !filereadable(l:file)
return ''
endif
endif
"
" Gather candidate files
"
let l:path = expand('%:p:h')
let l:dirs = l:path
2014-07-17 12:43:44 -04:00
while l:path != fnamemodify(l:path, ':h')
let l:path = fnamemodify(l:path, ':h')
let l:dirs .= ',' . l:path
endwhile
let l:candidates = split(globpath(fnameescape(l:dirs), '*.tex'), '\n')
"
" Search through candidates
"
for l:cand in l:candidates
2015-04-23 01:49:09 -04:00
" Avoid infinite recursion (checking the same file repeatedly)
if l:cand == l:file | continue | endif
2015-04-23 01:49:09 -04:00
let l:file_re = '\s*((.*)\/)?' . fnamemodify(l:file, ':t:r')
let l:filter = 'v:val =~# ''\v'
2016-02-16 16:35:09 -05:00
let l:filter .= '\\%(input|include)\{' . l:file_re
let l:filter .= '|\\subimport\{[^\}]*\}\{' . l:file_re
let l:filter .= ''''
if len(filter(readfile(l:cand), l:filter)) > 0
2016-09-01 16:13:21 -04:00
return s:get_main_recurse(fnamemodify(l:cand, ':p'))
endif
endfor
2013-10-05 07:53:42 -04:00
endfunction
" }}}1
function! s:file_is_main(file) " {{{1
"
" Check if a:file is a main file
"
return filereadable(a:file)
\ && len(filter(readfile(a:file, 0, 50),
\ 'v:val =~# ''\C\\documentclass\_\s*[\[{]''')) > 0
endfunction
" }}}1
function! s:file_reaches_current(file) " {{{1
if !filereadable(a:file) | return 0 | endif
for l:line in readfile(a:file)
let l:file = matchstr(l:line,
\ '\v\\%(input|include|subimport\{[^\}]*\})\s*\{\zs'
\ . '((.*)\/)?[a-zA-Z._-]+')
if empty(l:file) | continue | endif
if l:file[0] !=# '/'
let l:file = fnamemodify(a:file, ':h') . '/' . l:file
endif
if expand('%:p') ==# l:file
\ || s:file_reaches_current(l:file)
return 1
endif
endfor
return 0
endfunction
2016-08-04 16:12:18 -04:00
" }}}1
function! s:get_log() dict " {{{1
return self.ext('log')
endfunction
" }}}1
function! s:get_aux() dict " {{{1
return self.ext('aux')
endfunction
" }}}1
2016-10-02 09:56:19 -04:00
function! s:get_out(...) dict " {{{1
return call(self.ext, ['pdf'] + a:000, self)
2016-08-04 16:12:18 -04:00
endfunction
" }}}1
2016-10-02 09:56:19 -04:00
function! s:get_ext(ext, ...) dict " {{{1
" First check build dir (latexmk -output_directory option)
if g:vimtex_latexmk_build_dir !=# ''
2016-08-04 16:12:18 -04:00
let cand = g:vimtex_latexmk_build_dir . '/' . self.name . '.' . a:ext
if g:vimtex_latexmk_build_dir[0] !=# '/'
2016-08-04 16:12:18 -04:00
let cand = self.root . '/' . cand
2013-10-05 07:53:42 -04:00
endif
2016-10-02 09:56:19 -04:00
if a:0 > 0 || filereadable(cand)
return fnamemodify(cand, ':p')
endif
endif
" Next check for file in project root folder
2016-08-04 16:12:18 -04:00
let cand = self.root . '/' . self.name . '.' . a:ext
2016-10-02 09:56:19 -04:00
if a:0 > 0 || filereadable(cand)
return fnamemodify(cand, ':p')
endif
" Finally return empty string if no entry is found
return ''
endfunction
2015-02-27 02:30:58 -05:00
" }}}1
2015-06-20 17:16:53 -04:00
function! s:filename_changed_pre() " {{{1
let thisfile = fnamemodify(expand('%'), ':p')
let s:filename_changed = thisfile ==# b:vimtex.tex
let s:filename_old = b:vimtex.base
2015-06-20 17:16:53 -04:00
endfunction
" }}}1
function! s:filename_changed_post() " {{{1
if s:filename_changed
2015-06-20 17:16:53 -04:00
let b:vimtex.tex = fnamemodify(expand('%'), ':p')
let b:vimtex.base = fnamemodify(b:vimtex.tex, ':t')
let b:vimtex.name = fnamemodify(b:vimtex.tex, ':t:r')
let message = ['vimtex: ',
\ ['VimtexWarning', 'Filename change detected!'],
\ "\n Old filename: ", ['VimtexInfo', s:filename_old],
\ "\n New filename: ", ['VimtexInfo', b:vimtex.base]]
if b:vimtex.pid
let message += ["\n latexmk process: ",
\ ['VimtexInfo', b:vimtex.pid],
\ ['VimtexWarning', ' killed!']]
call vimtex#latexmk#stop()
endif
call vimtex#echo#status(message)
2015-06-20 17:16:53 -04:00
endif
endfunction
" }}}1
2015-02-27 02:30:58 -05:00
function! s:print_dict(dict, ...) " {{{1
let level = a:0 > 0 ? a:1 : 0
for entry in sort(sort(items(a:dict),
2015-03-20 16:30:59 -04:00
\ 's:print_dict_sort_2'),
\ 's:print_dict_sort_1')
let title = repeat(' ', 2 + 2*level) . entry[0]
2015-02-27 02:30:58 -05:00
if type(entry[1]) == type([])
call vimtex#echo#echo(title)
2015-02-27 02:30:58 -05:00
for val in entry[1]
call vimtex#echo#echo(repeat(' ', 4 + 2*level) . string(val), 'None')
2015-02-27 02:30:58 -05:00
endfor
elseif type(entry[1]) == type({})
call vimtex#echo#echo(title . "\n")
2015-02-27 02:30:58 -05:00
call s:print_dict(entry[1], level + 1)
else
call vimtex#echo#formatted([title . ' : ',
\ ['None', string(entry[1]) . "\n"]])
2015-02-27 02:30:58 -05:00
endif
endfor
2013-10-05 07:53:42 -04:00
endfunction
2015-02-27 02:30:58 -05:00
" }}}1
function! s:print_dict_sort_1(i1, i2) " {{{1
return type(a:i1[1]) - type(a:i2[1])
endfunction
" }}}1
function! s:print_dict_sort_2(i1, i2) " {{{1
return string(a:i1[1]) == string(a:i2[1]) ? 0
\ : string(a:i1[1]) > string(a:i2[1]) ? 1
\ : -1
endfunction
2013-10-05 07:53:42 -04:00
" }}}1
function! s:buffer_left() " {{{1
let s:vimtex_id = b:vimtex_id
endfunction
" }}}1
function! s:buffer_deleted(...) " {{{1
"
" Get the relevant blob id
"
let l:vimtex_id = a:0 > 0 ? a:1 : get(s:, 'vimtex_id', -1)
if exists('s:vimtex_id') | unlet s:vimtex_id | endif
if !has_key(g:vimtex_data, l:vimtex_id) | return | endif
"
" Count the number of open buffers for the given blob
"
let l:buffers = filter(range(1, bufnr('$')), 'buflisted(v:val)')
let l:vimtex_ids = map(l:buffers, 'getbufvar(v:val, ''vimtex_id'', -1)')
let l:count = count(l:vimtex_ids, l:vimtex_id)
2015-11-10 04:35:12 -05:00
"
" Check if the deleted buffer was the last remaining buffer of an opened
" latex project
2015-11-10 04:35:12 -05:00
"
if l:count <= 1
let l:vimtex = remove(g:vimtex_data, l:vimtex_id)
2015-11-10 04:35:12 -05:00
if exists('#User#VimtexEventQuit')
if exists('b:vimtex')
let b:vimtex_tmp = b:vimtex
endif
let b:vimtex = l:vimtex
doautocmd User VimtexEventQuit
if exists('b:vimtex_tmp')
2016-09-08 16:18:04 -04:00
let b:vimtex = b:vimtex_tmp
2015-11-10 04:35:12 -05:00
unlet b:vimtex_tmp
else
unlet b:vimtex
endif
endif
endif
endfunction
" }}}1
2014-12-08 14:44:17 -05:00
" vim: fdm=marker sw=2