diff options
author | Adam Stankiewicz <sheerun@sher.pl> | 2017-12-06 13:17:06 +0100 |
---|---|---|
committer | Adam Stankiewicz <sheerun@sher.pl> | 2017-12-06 13:17:06 +0100 |
commit | 11f53253ad9fd0cd3e7a44ed9f8c80a4f265b46e (patch) | |
tree | 08649366f6babad66db065b341691cfac02c2c4a /ftplugin/latex-box/complete.vim | |
parent | 9fe009095afdb86f6f771109ac454ccfc5340f31 (diff) | |
download | vim-polyglot-3.2.0.tar.gz vim-polyglot-3.2.0.zip |
Add slime syntax, closes #252v3.2.0
Diffstat (limited to 'ftplugin/latex-box/complete.vim')
-rw-r--r-- | ftplugin/latex-box/complete.vim | 936 |
1 files changed, 0 insertions, 936 deletions
diff --git a/ftplugin/latex-box/complete.vim b/ftplugin/latex-box/complete.vim deleted file mode 100644 index aecb0d8d..00000000 --- a/ftplugin/latex-box/complete.vim +++ /dev/null @@ -1,936 +0,0 @@ -if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1 - -" LaTeX Box completion - -setlocal omnifunc=LatexBox_Complete - -" <SID> Wrap {{{ -function! s:GetSID() - return matchstr(expand('<sfile>'), '\zs<SNR>\d\+_\ze.*$') -endfunction -let s:SID = s:GetSID() -function! s:SIDWrap(func) - return s:SID . a:func -endfunction -" }}} - -" Completion {{{ -if !exists('g:LatexBox_completion_close_braces') - let g:LatexBox_completion_close_braces = 1 -endif -if !exists('g:LatexBox_bibtex_wild_spaces') - let g:LatexBox_bibtex_wild_spaces = 1 -endif - -if !exists('g:LatexBox_cite_pattern') - let g:LatexBox_cite_pattern = '\C\\\a*cite\a*\*\?\(\[[^\]]*\]\)*\_\s*{' -endif -if !exists('g:LatexBox_ref_pattern') - let g:LatexBox_ref_pattern = '\C\\v\?\(eq\|page\|[cC]\|labelc\|name\|auto\)\?ref\*\?\_\s*{' -endif - -if !exists('g:LatexBox_completion_environments') - let g:LatexBox_completion_environments = [ - \ {'word': 'itemize', 'menu': 'bullet list' }, - \ {'word': 'enumerate', 'menu': 'numbered list' }, - \ {'word': 'description', 'menu': 'description' }, - \ {'word': 'center', 'menu': 'centered text' }, - \ {'word': 'figure', 'menu': 'floating figure' }, - \ {'word': 'table', 'menu': 'floating table' }, - \ {'word': 'equation', 'menu': 'equation (numbered)' }, - \ {'word': 'align', 'menu': 'aligned equations (numbered)' }, - \ {'word': 'align*', 'menu': 'aligned equations' }, - \ {'word': 'document' }, - \ {'word': 'abstract' }, - \ ] -endif - -if !exists('g:LatexBox_completion_commands') - let g:LatexBox_completion_commands = [ - \ {'word': '\begin{' }, - \ {'word': '\end{' }, - \ {'word': '\item' }, - \ {'word': '\label{' }, - \ {'word': '\ref{' }, - \ {'word': '\eqref{eq:' }, - \ {'word': '\cite{' }, - \ {'word': '\chapter{' }, - \ {'word': '\section{' }, - \ {'word': '\subsection{' }, - \ {'word': '\subsubsection{' }, - \ {'word': '\paragraph{' }, - \ {'word': '\nonumber' }, - \ {'word': '\bibliography' }, - \ {'word': '\bibliographystyle' }, - \ ] -endif - -if !exists('g:LatexBox_complete_inlineMath') - let g:LatexBox_complete_inlineMath = 0 -endif - -if !exists('g:LatexBox_eq_env_patterns') - let g:LatexBox_eq_env_patterns = 'equation\|gather\|multiline\|align\|flalign\|alignat\|eqnarray' -endif - -" }}} - -"LatexBox_kpsewhich {{{ -function! LatexBox_kpsewhich(file) - let old_dir = getcwd() - execute 'lcd ' . fnameescape(LatexBox_GetTexRoot()) - let out = system('kpsewhich "' . a:file . '"') - - " If kpsewhich has found something, it returns a non-empty string with a - " newline at the end; otherwise the string is empty - if len(out) - " Remove the trailing newline - let out = fnamemodify(out[:-2], ':p') - endif - - execute 'lcd ' . fnameescape(old_dir) - - return out -endfunction -"}}} - -" Omni Completion {{{ - -let s:completion_type = '' - -function! LatexBox_Complete(findstart, base) - if a:findstart - " return the starting position of the word - let line = getline('.') - let pos = col('.') - 1 - while pos > 0 && line[pos - 1] !~ '\\\|{' - let pos -= 1 - endwhile - - let line_start = line[:pos-1] - if line_start =~ '\m\C\\begin\_\s*{$' - let s:completion_type = 'begin' - elseif line_start =~ '\m\C\\end\_\s*{$' - let s:completion_type = 'end' - elseif line_start =~ '\m' . g:LatexBox_ref_pattern . '$' - let s:completion_type = 'ref' - elseif line_start =~ '\m' . g:LatexBox_cite_pattern . '$' - let s:completion_type = 'bib' - " check for multiple citations - let pos = col('.') - 1 - while pos > 0 && line[pos - 1] !~ '{\|,' - let pos -= 1 - endwhile - elseif s:LatexBox_complete_inlineMath_or_not() - let s:completion_type = 'inlineMath' - let pos = s:eq_pos - else - let s:completion_type = 'command' - if line[pos - 1] == '\' - let pos -= 1 - endif - endif - return pos - else - " return suggestions in an array - let suggestions = [] - - if s:completion_type == 'begin' - " suggest known environments - for entry in g:LatexBox_completion_environments - if entry.word =~ '^' . escape(a:base, '\') - if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^}') - " add trailing '}' - let entry = copy(entry) - let entry.abbr = entry.word - let entry.word = entry.word . '}' - endif - call add(suggestions, entry) - endif - endfor - elseif s:completion_type == 'end' - " suggest known environments - let env = LatexBox_GetCurrentEnvironment() - if env != '' - if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^\s*[,}]') - call add(suggestions, {'word': env . '}', 'abbr': env}) - else - call add(suggestions, env) - endif - endif - elseif s:completion_type == 'command' - " suggest known commands - for entry in g:LatexBox_completion_commands - if entry.word =~ '^' . escape(a:base, '\') - " do not display trailing '{' - if entry.word =~ '{' - let entry.abbr = entry.word[0:-2] - endif - call add(suggestions, entry) - endif - endfor - elseif s:completion_type == 'ref' - let suggestions = s:CompleteLabels(a:base) - elseif s:completion_type == 'bib' - " suggest BibTeX entries - let suggestions = LatexBox_BibComplete(a:base) - elseif s:completion_type == 'inlineMath' - let suggestions = s:LatexBox_inlineMath_completion(a:base) - endif - if !has('gui_running') - redraw! - endif - return suggestions - endif -endfunction -" }}} - -" BibTeX search {{{ - -" find the \bibliography{...} commands -" the optional argument is the file name to be searched - -function! s:FindBibData(...) - if a:0 == 0 - let file = LatexBox_GetMainTexFile() - else - let file = a:1 - endif - - if !filereadable(file) - return [] - endif - let lines = readfile(file) - let bibdata_list = [] - - " - " Search for added bibliographies - " - let bibliography_cmds = [ - \ '\\bibliography', - \ '\\addbibresource', - \ '\\addglobalbib', - \ '\\addsectionbib', - \ ] - for cmd in bibliography_cmds - let filtered = filter(copy(lines), - \ 'v:val =~ ''\C' . cmd . '\s*{[^}]\+}''') - let files = map(filtered, - \ 'matchstr(v:val, ''\C' . cmd . '\s*{\zs[^}]\+\ze}'')') - for file in files - let bibdata_list += map(split(file, ','), - \ 'fnamemodify(v:val, '':r'')') - endfor - endfor - - " - " Also search included files - " - for input in filter(lines, - \ 'v:val =~ ''\C\\\%(input\|include\)\s*{[^}]\+}''') - let bibdata_list += s:FindBibData(LatexBox_kpsewhich( - \ matchstr(input, - \ '\C\\\%(input\|include\)\s*{\zs[^}]\+\ze}'))) - endfor - - return bibdata_list -endfunction - -let s:bstfile = expand('<sfile>:p:h') . '/vimcomplete' - -function! LatexBox_BibSearch(regexp) - let res = [] - - " Find data from bib files - let bibdata = join(s:FindBibData(), ',') - if bibdata != '' - - " write temporary aux file - let tmpbase = LatexBox_GetTexRoot() . '/_LatexBox_BibComplete' - let auxfile = tmpbase . '.aux' - let bblfile = tmpbase . '.bbl' - let blgfile = tmpbase . '.blg' - - call writefile(['\citation{*}', '\bibstyle{' . s:bstfile . '}', - \ '\bibdata{' . bibdata . '}'], auxfile) - - if has('win32') - let l:old_shellslash = &l:shellslash - setlocal noshellslash - call system('cd ' . shellescape(LatexBox_GetTexRoot()) . - \ ' & bibtex -terse ' - \ . fnamemodify(auxfile, ':t') . ' >nul') - let &l:shellslash = l:old_shellslash - else - call system('cd ' . shellescape(LatexBox_GetTexRoot()) . - \ ' ; bibtex -terse ' - \ . fnamemodify(auxfile, ':t') . ' >/dev/null') - endif - - let lines = split(substitute(join(readfile(bblfile), "\n"), - \ '\n\n\@!\(\s\=\)\s*\|{\|}', '\1', 'g'), "\n") - - for line in filter(lines, 'v:val =~ a:regexp') - let matches = matchlist(line, - \ '^\(.*\)||\(.*\)||\(.*\)||\(.*\)||\(.*\)') - if !empty(matches) && !empty(matches[1]) - let s:type_length = max([s:type_length, - \ len(matches[2]) + 3]) - call add(res, { - \ 'key': matches[1], - \ 'type': matches[2], - \ 'author': matches[3], - \ 'year': matches[4], - \ 'title': matches[5], - \ }) - endif - endfor - - call delete(auxfile) - call delete(bblfile) - call delete(blgfile) - endif - - " Find data from 'thebibliography' environments - let lines = readfile(LatexBox_GetMainTexFile()) - if match(lines, '\C\\begin{thebibliography}') >= 0 - for line in filter(filter(lines, 'v:val =~ ''\C\\bibitem'''), - \ 'v:val =~ a:regexp') - let match = matchlist(line, '\\bibitem{\([^}]*\)')[1] - call add(res, { - \ 'key': match, - \ 'type': '', - \ 'author': '', - \ 'year': '', - \ 'title': match, - \ }) - endfor - endif - - return res -endfunction -" }}} - -" BibTeX completion {{{ -let s:type_length=0 -function! LatexBox_BibComplete(regexp) - - " treat spaces as '.*' if needed - if g:LatexBox_bibtex_wild_spaces - "let regexp = substitute(a:regexp, '\s\+', '.*', 'g') - let regexp = '.*' . substitute(a:regexp, '\s\+', '\\\&.*', 'g') - else - let regexp = a:regexp - endif - - let res = [] - let s:type_length = 4 - for m in LatexBox_BibSearch(regexp) - let type = m['type'] == '' ? '[-]' : '[' . m['type'] . '] ' - let type = printf('%-' . s:type_length . 's', type) - let auth = m['author'] == '' ? '' : m['author'][:20] . ' ' - let auth = substitute(auth, '\~', ' ', 'g') - let auth = substitute(auth, ',.*\ze', ' et al. ', '') - let year = m['year'] == '' ? '' : '(' . m['year'] . ')' - let w = { 'word': m['key'], - \ 'abbr': type . auth . year, - \ 'menu': m['title'] } - - " close braces if needed - if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^\s*[,}]') - let w.word = w.word . '}' - endif - - call add(res, w) - endfor - return res -endfunction -" }}} - -" ExtractLabels {{{ -" Generate list of \newlabel commands in current buffer. -" -" Searches the current buffer for commands of the form -" \newlabel{name}{{number}{page}.* -" and returns list of [ name, number, page ] tuples. -function! s:ExtractLabels() - call cursor(1,1) - - let matches = [] - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - - while [lblline, lblbegin] != [0,0] - let [nln, nameend] = searchpairpos( '{', '', '}', 'W' ) - if nln != lblline - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - continue - endif - let curname = strpart( getline( lblline ), lblbegin, nameend - lblbegin - 1 ) - - " Ignore cref entries (because they are duplicates) - if curname =~# "@cref$" - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - continue - endif - - if 0 == search( '\m{\w*{', 'ce', lblline ) - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - continue - endif - - let numberbegin = getpos('.')[2] - let [nln, numberend] = searchpairpos( '{', '', '}', 'W' ) - if nln != lblline - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - continue - endif - let curnumber = strpart( getline( lblline ), numberbegin, numberend - numberbegin - 1 ) - - if 0 == search( '\m\w*{', 'ce', lblline ) - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - continue - endif - - let pagebegin = getpos('.')[2] - let [nln, pageend] = searchpairpos( '{', '', '}', 'W' ) - if nln != lblline - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - continue - endif - let curpage = strpart( getline( lblline ), pagebegin, pageend - pagebegin - 1 ) - - let matches += [ [ curname, curnumber, curpage ] ] - - let [lblline, lblbegin] = searchpos( '\\newlabel{', 'ecW' ) - endwhile - - return matches -endfunction -"}}} - -" ExtractInputs {{{ -" Generate list of \@input commands in current buffer. -" -" Searches the current buffer for \@input{file} entries and -" returns list of all files. -function! s:ExtractInputs() - call cursor(1,1) - - let matches = [] - let [inline, inbegin] = searchpos( '\\@input{', 'ecW' ) - - while [inline, inbegin] != [0,0] - let [nln, inend] = searchpairpos( '{', '', '}', 'W' ) - if nln != inline - let [inline, inbegin] = searchpos( '\\@input{', 'ecW' ) - continue - endif - let matches += [ LatexBox_kpsewhich(strpart( getline( inline ), inbegin, inend - inbegin - 1 )) ] - - let [inline, inbegin] = searchpos( '\\@input{', 'ecW' ) - endwhile - - " Remove empty strings for nonexistant .aux files - return filter(matches, 'v:val != ""') -endfunction -"}}} - -" LabelCache {{{ -" Cache of all labels. -" -" LabelCache is a dictionary mapping filenames to tuples -" [ time, labels, inputs ] -" where -" * time is modification time of the cache entry -" * labels is a list like returned by ExtractLabels -" * inputs is a list like returned by ExtractInputs -let s:LabelCache = {} -"}}} - -" GetLabelCache {{{ -" Extract labels from LabelCache and update it. -" -" Compares modification time of each entry in the label -" cache and updates it, if necessary. During traversal of -" the LabelCache, all current labels are collected and -" returned. -function! s:GetLabelCache(file) - if !filereadable(a:file) - return [] - endif - - if !has_key(s:LabelCache , a:file) || s:LabelCache[a:file][0] != getftime(a:file) - " Open file in temporary split window for label extraction. - let main_tex_file = LatexBox_GetMainTexFile() - silent execute '1sp +let\ b:main_tex_file=main_tex_file|let\ labels=s:ExtractLabels()|let\ inputs=s:ExtractInputs()|quit! ' . fnameescape(a:file) - let s:LabelCache[a:file] = [ getftime(a:file), labels, inputs ] - endif - - " We need to create a copy of s:LabelCache[fid][1], otherwise all inputs' - " labels would be added to the current file's label cache upon each - " completion call, leading to duplicates/triplicates/etc. and decreased - " performance. - " Also, because we don't anything with the list besides matching copies, - " we can get away with a shallow copy for now. - let labels = copy(s:LabelCache[a:file][1]) - - for input in s:LabelCache[a:file][2] - let labels += s:GetLabelCache(input) - endfor - - return labels -endfunction -"}}} - -" Complete Labels {{{ -function! s:CompleteLabels(regex) - let labels = s:GetLabelCache(LatexBox_GetAuxFile()) - - let matches = filter( copy(labels), 'match(v:val[0], "' . a:regex . '") != -1' ) - if empty(matches) - " also try to match label and number - let regex_split = split(a:regex) - if len(regex_split) > 1 - let base = regex_split[0] - let number = escape(join(regex_split[1:], ' '), '.') - let matches = filter( copy(labels), 'match(v:val[0], "' . base . '") != -1 && match(v:val[1], "' . number . '") != -1' ) - endif - endif - if empty(matches) - " also try to match number - let matches = filter( copy(labels), 'match(v:val[1], "' . a:regex . '") != -1' ) - endif - - let suggestions = [] - for m in matches - let entry = {'word': m[0], 'menu': printf("%7s [p. %s]", '('.m[1].')', m[2])} - if g:LatexBox_completion_close_braces && !s:NextCharsMatch('^\s*[,}]') - " add trailing '}' - let entry = copy(entry) - let entry.abbr = entry.word - let entry.word = entry.word . '}' - endif - call add(suggestions, entry) - endfor - - return suggestions -endfunction -" }}} - -" Complete Inline Math Or Not {{{ -" Return 1, when cursor is in a math env: -" 1, there is a single $ in the current line on the left of cursor -" 2, there is an open-eq-env on/above the current line -" (open-eq-env : \(, \[, and \begin{eq-env} ) -" Return 0, when cursor is not in a math env -function! s:LatexBox_complete_inlineMath_or_not() - - " switch of inline math completion feature - if g:LatexBox_complete_inlineMath == 0 - return 0 - endif - - " env names that can't appear in an eq env - if !exists('s:LatexBox_doc_structure_patterns') - let s:LatexBox_doc_structure_patterns = '\%(' . '\\begin\s*{document}\|' . - \ '\\\%(chapter\|section\|subsection\|subsubsection\)\*\?\s*{' . '\)' - endif - - if !exists('s:LatexBox_eq_env_open_patterns') - let s:LatexBox_eq_env_open_patterns = ['\\(','\\\['] - endif - if !exists('s:LatexBox_eq_env_close_patterns') - let s:LatexBox_eq_env_close_patterns = ['\\)','\\\]'] - endif - - let notcomment = '\%(\%(\\\@<!\%(\\\\\)*\)\@<=%.*\)\@<!' - - let lnum_saved = line('.') - let cnum_saved = col('.') -1 - - let line = getline('.') - let line_start_2_cnum_saved = line[:cnum_saved] - - " determine whether there is a single $ before cursor - let cursor_dollar_pair = 0 - while matchend(line_start_2_cnum_saved, '\$[^$]\+\$', cursor_dollar_pair) >= 0 - " find the end of dollar pair - let cursor_dollar_pair = matchend(line_start_2_cnum_saved, '\$[^$]\+\$', cursor_dollar_pair) - endwhile - " find single $ after cursor_dollar_pair - let cursor_single_dollar = matchend(line_start_2_cnum_saved, '\$', cursor_dollar_pair) - - " if single $ is found - if cursor_single_dollar >= 0 - " check whether $ is in \(...\), \[...\], or \begin{eq}...\end{eq} - - " check current line, - " search for LatexBox_eq_env_close_patterns: \[ and \( - let lnum = line('.') - for i in range(0, (len(s:LatexBox_eq_env_open_patterns)-1)) - call cursor(lnum_saved, cnum_saved) - let cnum_close = searchpos(''. s:LatexBox_eq_env_close_patterns[i].'', 'cbW', lnum_saved)[1] - let cnum_open = matchend(line_start_2_cnum_saved, s:LatexBox_eq_env_open_patterns[i], cnum_close) - if cnum_open >= 0 - let s:eq_dollar_parenthesis_bracket_empty = '' - let s:eq_pos = cursor_single_dollar - 1 - return 1 - end - endfor - - " check the lines above - " search for s:LatexBox_doc_structure_patterns, and end-of-math-env - let lnum -= 1 - while lnum > 0 - let line = getline(lnum) - if line =~ notcomment . '\(' . s:LatexBox_doc_structure_patterns . - \ '\|' . '\\end\s*{\(' . g:LatexBox_eq_env_patterns . '\)\*\?}\)' - " when s:LatexBox_doc_structure_patterns or g:LatexBox_eq_env_patterns - " are found first, complete math, leave with $ at both sides - let s:eq_dollar_parenthesis_bracket_empty = '$' - let s:eq_pos = cursor_single_dollar - break - elseif line =~ notcomment . '\\begin\s*{\(' . g:LatexBox_eq_env_patterns . '\)\*\?}' - " g:LatexBox_eq_env_patterns is found, complete math, remove $ - let s:eq_dollar_parenthesis_bracket_empty = '' - let s:eq_pos = cursor_single_dollar - 1 - break - endif - let lnum -= 1 - endwhile - - return 1 - else - " no $ is found, then search for \( or \[ in current line - " 1, whether there is \( - call cursor(lnum_saved, cnum_saved) - let cnum_parenthesis_close = searchpos('\\)', 'cbW', lnum_saved)[1] - let cnum_parenthesis_open = matchend(line_start_2_cnum_saved, '\\(', cnum_parenthesis_close) - if cnum_parenthesis_open >= 0 - let s:eq_dollar_parenthesis_bracket_empty = '\)' - let s:eq_pos = cnum_parenthesis_open - return 1 - end - - " 2, whether there is \[ - call cursor(lnum_saved, cnum_saved) - let cnum_bracket_close = searchpos('\\\]', 'cbW', lnum_saved)[1] - let cnum_bracket_open = matchend(line_start_2_cnum_saved, '\\\[', cnum_bracket_close) - if cnum_bracket_open >= 0 - let s:eq_dollar_parenthesis_bracket_empty = '\]' - let s:eq_pos = cnum_bracket_open - return 1 - end - - " not inline math completion - return 0 - endif - -endfunction -" }}} - -" Complete inline euqation{{{ -function! s:LatexBox_inlineMath_completion(regex, ...) - - if a:0 == 0 - let file = LatexBox_GetMainTexFile() - else - let file = a:1 - endif - - if empty(glob(file, 1)) - return '' - endif - - if empty(s:eq_dollar_parenthesis_bracket_empty) - let inline_pattern1 = '\$\s*\(' . escape(substitute(a:regex[1:], '^\s\+', '', ""), '\.*^') . '[^$]*\)\s*\$' - let inline_pattern2 = '\\(\s*\(' . escape(substitute(a:regex[1:], '^\s\+', '', ""), '\.*^') . '.*\)\s*\\)' - else - let inline_pattern1 = '\$\s*\(' . escape(substitute(a:regex, '^\s\+', '', ""), '\.*^') . '[^$]*\)\s*\$' - let inline_pattern2 = '\\(\s*\(' . escape(substitute(a:regex, '^\s\+', '', ""), '\.*^') . '.*\)\s*\\)' - endif - - - let suggestions = [] - let line_num = 0 - for line in readfile(file) - let line_num = line_num + 1 - - let suggestions += s:LatexBox_inlineMath_mathlist(line,inline_pattern1 , line_num) + s:LatexBox_inlineMath_mathlist( line,inline_pattern2, line_num) - - " search for included files - let included_file = matchstr(line, '^\\@input{\zs[^}]*\ze}') - if included_file != '' - let included_file = LatexBox_kpsewhich(included_file) - call extend(suggestions, s:LatexBox_inlineMath_completion(a:regex, included_file)) - endif - endfor - - return suggestions -endfunction -" }}} - -" Search for inline maths {{{ -" search for $ ... $ and \( ... \) in each line -function! s:LatexBox_inlineMath_mathlist(line,inline_pattern, line_num) - let col_start = 0 - let suggestions = [] - while 1 - let matches = matchlist(a:line, a:inline_pattern, col_start) - if !empty(matches) - - " show line number of inline math - let entry = {'word': matches[1], 'menu': '[' . a:line_num . ']'} - - if s:eq_dollar_parenthesis_bracket_empty != '' - let entry = copy(entry) - let entry.abbr = entry.word - let entry.word = entry.word . s:eq_dollar_parenthesis_bracket_empty - endif - call add(suggestions, entry) - - " update col_start - let col_start = matchend(a:line, a:inline_pattern, col_start) - else - break - endif - endwhile - - return suggestions -endfunction -" }}} - -" Close Current Environment {{{ -function! s:CloseCurEnv() - " first, try with \left/\right pairs - let [lnum, cnum] = searchpairpos('\C\\left\>', '', '\C\\right\>', 'bnW', 'LatexBox_InComment()') - if lnum - let line = strpart(getline(lnum), cnum - 1) - let bracket = matchstr(line, '^\\left\zs\((\|\[\|\\{\||\|\.\)\ze') - for [open, close] in [['(', ')'], ['\[', '\]'], ['\\{', '\\}'], ['|', '|'], ['\.', '|']] - let bracket = substitute(bracket, open, close, 'g') - endfor - return '\right' . bracket - endif - - " second, try with environments - let env = LatexBox_GetCurrentEnvironment() - if env == '\[' - return '\]' - elseif env == '\(' - return '\)' - elseif env != '' - return '\end{' . env . '}' - endif - return '' -endfunction -" }}} - -" Wrap Selection {{{ -function! s:WrapSelection(wrapper) - keepjumps normal! `>a} - execute 'keepjumps normal! `<i\' . a:wrapper . '{' -endfunction -" }}} - -" Wrap Selection in Environment with Prompt {{{ -function! s:PromptEnvWrapSelection(...) - let env = input('environment: ', '', 'customlist,' . s:SIDWrap('GetEnvironmentList')) - if empty(env) - return - endif - " LaTeXBox's custom indentation can interfere with environment - " insertion when environments are indented (common for nested - " environments). Temporarily disable it for this operation: - let ieOld = &indentexpr - setlocal indentexpr="" - if visualmode() ==# 'V' - execute 'keepjumps normal! `>o\end{' . env . '}' - execute 'keepjumps normal! `<O\begin{' . env . '}' - " indent and format, if requested. - if a:0 && a:1 - normal! gv> - normal! gvgq - endif - else - execute 'keepjumps normal! `>a\end{' . env . '}' - execute 'keepjumps normal! `<i\begin{' . env . '}' - endif - exe "setlocal indentexpr=" . ieOld -endfunction -" }}} - -" List Labels with Prompt {{{ -function! s:PromptLabelList(...) - " Check if window already exists - let winnr = bufwinnr(bufnr('LaTeX Labels')) - if winnr >= 0 - if a:0 == 0 - silent execute winnr . 'wincmd w' - else - " Supplying an argument to this function causes toggling instead - " of jumping to the labels window - if g:LatexBox_split_resize - silent exe "set columns-=" . g:LatexBox_split_width - endif - silent execute 'bwipeout' . bufnr('LaTeX Labels') - endif - return - endif - - " Get label suggestions - let regexp = input('filter labels with regexp: ', '') - let labels = s:CompleteLabels(regexp) - - let calling_buf = bufnr('%') - - " Create labels window and set local settings - if g:LatexBox_split_resize - silent exe "set columns+=" . g:LatexBox_split_width - endif - silent exe g:LatexBox_split_side g:LatexBox_split_width . 'vnew LaTeX\ Labels' - let b:toc = [] - let b:toc_numbers = 1 - let b:calling_win = bufwinnr(calling_buf) - setlocal filetype=latextoc - - " Add label entries and jump to the closest section - for entry in labels - let number = matchstr(entry['menu'], '^\s*(\zs[^)]\+\ze)') - let page = matchstr(entry['menu'], '^[^)]*)\s*\[\zs[^]]\+\ze\]') - let e = {'file': bufname(calling_buf), - \ 'level': 'label', - \ 'number': number, - \ 'text': entry['abbr'], - \ 'page': page} - call add(b:toc, e) - if b:toc_numbers - call append('$', e['number'] . "\t" . e['text']) - else - call append('$', e['text']) - endif - endfor - if !g:LatexBox_toc_hidehelp - call append('$', "") - call append('$', "<Esc>/q: close") - call append('$', "<Space>: jump") - call append('$', "<Enter>: jump and close") - call append('$', "s: hide numbering") - endif - 0delete _ - - " Lock buffer - setlocal nomodifiable -endfunction -" }}} - -" Change Environment {{{ -function! s:ChangeEnvPrompt() - - let [env, lnum, cnum, lnum2, cnum2] = LatexBox_GetCurrentEnvironment(1) - - let new_env = input('change ' . env . ' for: ', '', 'customlist,' . s:SIDWrap('GetEnvironmentList')) - if empty(new_env) - return - endif - - if new_env == '\[' || new_env == '[' - let begin = '\[' - let end = '\]' - elseif new_env == '\(' || new_env == '(' - let begin = '\(' - let end = '\)' - else - let l:begin = '\begin{' . new_env . '}' - let l:end = '\end{' . new_env . '}' - endif - - if env == '\[' || env == '\(' - let line = getline(lnum2) - let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + 1) - call setline(lnum2, line) - - let line = getline(lnum) - let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + 1) - call setline(lnum, line) - else - let line = getline(lnum2) - let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + len(env) + 5) - call setline(lnum2, line) - - let line = getline(lnum) - let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + len(env) + 7) - call setline(lnum, line) - endif -endfunction - -function! s:GetEnvironmentList(lead, cmdline, pos) - let suggestions = [] - for entry in g:LatexBox_completion_environments - let env = entry.word - if env =~ '^' . a:lead - call add(suggestions, env) - endif - endfor - return suggestions -endfunction - -function! s:LatexToggleStarEnv() - let [env, lnum, cnum, lnum2, cnum2] = LatexBox_GetCurrentEnvironment(1) - - if env == '\(' - return - elseif env == '\[' - let begin = '\begin{equation}' - let end = '\end{equation}' - elseif env[-1:] == '*' - let begin = '\begin{' . env[:-2] . '}' - let end = '\end{' . env[:-2] . '}' - else - let begin = '\begin{' . env . '*}' - let end = '\end{' . env . '*}' - endif - - if env == '\[' - let line = getline(lnum2) - let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + 1) - call setline(lnum2, line) - - let line = getline(lnum) - let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + 1) - call setline(lnum, line) - else - let line = getline(lnum2) - let line = strpart(line, 0, cnum2 - 1) . l:end . strpart(line, cnum2 + len(env) + 5) - call setline(lnum2, line) - - let line = getline(lnum) - let line = strpart(line, 0, cnum - 1) . l:begin . strpart(line, cnum + len(env) + 7) - call setline(lnum, line) - endif -endfunction -" }}} - -" Next Charaters Match {{{ -function! s:NextCharsMatch(regex) - let rest_of_line = strpart(getline('.'), col('.') - 1) - return rest_of_line =~ a:regex -endfunction -" }}} - -" Mappings {{{ -inoremap <silent> <Plug>LatexCloseCurEnv <C-R>=<SID>CloseCurEnv()<CR> -vnoremap <silent> <Plug>LatexWrapSelection :<c-u>call <SID>WrapSelection('')<CR>i -vnoremap <silent> <Plug>LatexEnvWrapSelection :<c-u>call <SID>PromptEnvWrapSelection()<CR> -vnoremap <silent> <Plug>LatexEnvWrapFmtSelection :<c-u>call <SID>PromptEnvWrapSelection(1)<CR> -nnoremap <silent> <Plug>LatexChangeEnv :call <SID>ChangeEnvPrompt()<CR> -nnoremap <silent> <Plug>LatexToggleStarEnv :call <SID>LatexToggleStarEnv()<CR> -" }}} - -" Commands {{{ -command! LatexLabels call <SID>PromptLabelList() -" }}} - -" vim:fdm=marker:ff=unix:noet:ts=4:sw=4 - -endif |