From 6d7b0abd16f9b64dc4895bbe57fc37a04843144b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Yngve=20Lerv=C3=A5g?= Date: Sat, 6 Jun 2015 23:49:28 +0200 Subject: [PATCH] A lot of convenient restructuring --- autoload/vimtex.vim | 324 ++++++++++++++++++++--------------- autoload/vimtex/change.vim | 20 ++- autoload/vimtex/complete.vim | 151 +++++++++++----- autoload/vimtex/echo.vim | 12 +- autoload/vimtex/fold.vim | 41 +++-- autoload/vimtex/index.vim | 11 +- autoload/vimtex/labels.vim | 29 ++-- autoload/vimtex/latexmk.vim | 69 ++++---- autoload/vimtex/mappings.vim | 12 +- autoload/vimtex/motion.vim | 136 ++++++++------- autoload/vimtex/toc.vim | 145 +++++++++------- autoload/vimtex/util.vim | 242 ++++++++++++-------------- autoload/vimtex/view.vim | 137 ++++++++------- doc/vimtex.txt | 14 ++ 14 files changed, 783 insertions(+), 560 deletions(-) diff --git a/autoload/vimtex.vim b/autoload/vimtex.vim index 90beb9b..5bb4eff 100644 --- a/autoload/vimtex.vim +++ b/autoload/vimtex.vim @@ -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(''), ':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 q :bwipeout - - " 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( == "!") - command! -buffer -bang VimtexWordCount call vimtex#wordcount( == "!") - - " Define mappings - nnoremap (vimtex-info) :call vimtex#info(0) -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( == "!") + command! -buffer -bang VimtexWordCount call vimtex#wordcount( == "!") + + " Define mappings + nnoremap (vimtex-info) :call vimtex#info(0) +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 q :bwipeout + + " 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 diff --git a/autoload/vimtex/change.vim b/autoload/vimtex/change.vim index 86723d9..fd0d495 100644 --- a/autoload/vimtex/change.vim +++ b/autoload/vimtex/change.vim @@ -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 (vimtex-delete-env) \ :call vimtex#change#env('') + nnoremap (vimtex-delete-cmd) vaBom`oxg``xdF\ \:silent! call repeat#set("\(vimtex-delete-cmd)", v:count) + nnoremap (vimtex-change-env) \ :call vimtex#change#env_prompt() + nnoremap (vimtex-change-cmd) \ :call vimtex#change#command() + nnoremap (vimtex-toggle-star) \ :call vimtex#change#toggle_env_star() + nnoremap (vimtex-toggle-delim) \ :call vimtex#change#toggle_delim() + nnoremap (vimtex-create-cmd) \ :call vimtex#change#to_command()i + inoremap (vimtex-create-cmd) \ =vimtex#change#to_command() + inoremap (vimtex-close-env) \ =vimtex#change#close_environment() endfunction +" }}}1 + function! vimtex#change#command() " {{{1 let pos_save = getpos('.') let savereg = @a diff --git a/autoload/vimtex/complete.vim b/autoload/vimtex/complete.vim index efaf31a..b367907 100644 --- a/autoload/vimtex/complete.vim +++ b/autoload/vimtex/complete.vim @@ -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%(%(\\@: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%(%(\\@: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 diff --git a/autoload/vimtex/echo.vim b/autoload/vimtex/echo.vim index f01041a..d9f911c 100644 --- a/autoload/vimtex/echo.vim +++ b/autoload/vimtex/echo.vim @@ -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 diff --git a/autoload/vimtex/fold.vim b/autoload/vimtex/fold.vim index f0f9b2b..88c6647 100644 --- a/autoload/vimtex/fold.vim +++ b/autoload/vimtex/fold.vim @@ -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 u :call FdmSave()u:call FdmRestore() - - " 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() diff --git a/autoload/vimtex/index.vim b/autoload/vimtex/index.vim index 2425db1..f7140a1 100644 --- a/autoload/vimtex/index.vim +++ b/autoload/vimtex/index.vim @@ -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 diff --git a/autoload/vimtex/labels.vim b/autoload/vimtex/labels.vim index fe920f5..2a252ab 100644 --- a/autoload/vimtex/labels.vim +++ b/autoload/vimtex/labels.vim @@ -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 diff --git a/autoload/vimtex/latexmk.vim b/autoload/vimtex/latexmk.vim index f8b2e9c..9c4b684 100644 --- a/autoload/vimtex/latexmk.vim +++ b/autoload/vimtex/latexmk.vim @@ -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 (vimtex-status-all) :call vimtex#latexmk#status(1) nnoremap (vimtex-lacheck) :call vimtex#latexmk#lacheck() - " 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 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 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 diff --git a/autoload/vimtex/mappings.vim b/autoload/vimtex/mappings.vim index d572eed..db524ba 100644 --- a/autoload/vimtex/mappings.vim +++ b/autoload/vimtex/mappings.vim @@ -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 li (vimtex-info) @@ -80,4 +88,6 @@ function! vimtex#mappings#init(initialized) endif endfunction +" }}}1 + " vim: fdm=marker sw=2 diff --git a/autoload/vimtex/motion.vim b/autoload/vimtex/motion.vim index 126d1cd..b628bcc 100644 --- a/autoload/vimtex/motion.vim +++ b/autoload/vimtex/motion.vim @@ -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 = '\%(\\\@' +endfunction + +" }}}1 +function! vimtex#motion#init_buffer() " {{{1 + if !g:vimtex_motion_enabled | return | endif - " Define mappings nnoremap (v) v nnoremap (vimtex-%) :call vimtex#motion#find_matching_pair() nnoremap (vimtex-]]) :call vimtex#motion#next_section(0,0,0) @@ -40,26 +107,10 @@ function! vimtex#motion#init(initialized) " {{{1 onoremap (vimtex-a$) :execute "normal \(v)\(vimtex-a$)" onoremap (vimtex-id) :execute "normal \(v)\(vimtex-id)" onoremap (vimtex-ad) :execute "normal \(v)\(vimtex-ad)" - - " 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 = '\%(\\\@' - -" }}}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 : '' diff --git a/autoload/vimtex/toc.vim b/autoload/vimtex/toc.vim index 2a3d0aa..4e518cf 100644 --- a/autoload/vimtex/toc.vim +++ b/autoload/vimtex/toc.vim @@ -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 (vimtex-toc-toggle) :call vimtex#toc#toggle() 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 diff --git a/autoload/vimtex/util.vim b/autoload/vimtex/util.vim index e2ce67d..a96835d 100644 --- a/autoload/vimtex/util.vim +++ b/autoload/vimtex/util.vim @@ -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 diff --git a/autoload/vimtex/view.vim b/autoload/vimtex/view.vim index f89ba33..e65f65e 100644 --- a/autoload/vimtex/view.vim +++ b/autoload/vimtex/view.vim @@ -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() - if has_key(b:vimtex.viewer, 'reverse_search') - command! -buffer -nargs=* VimtexRSearch - \ call b:vimtex.viewer.reverse_search() - endif - - " Define mappings - nnoremap (vimtex-view) - \ :call b:vimtex.viewer.view('') - if has_key(b:vimtex.viewer, 'reverse_search') - nnoremap (vimtex-reverse-search) - \ :call b:vimtex.viewer.reverse_search() - 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() + if has_key(b:vimtex.viewer, 'reverse_search') + command! -buffer -nargs=* VimtexRSearch + \ call b:vimtex.viewer.reverse_search() + endif + + " + " Define mappings + " + nnoremap (vimtex-view) + \ :call b:vimtex.viewer.view('') + if has_key(b:vimtex.viewer, 'reverse_search') + nnoremap (vimtex-reverse-search) + \ :call b:vimtex.viewer.reverse_search() + 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 diff --git a/doc/vimtex.txt b/doc/vimtex.txt index 31e7678..d400927 100644 --- a/doc/vimtex.txt +++ b/doc/vimtex.txt @@ -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,