diff options
Diffstat (limited to 'dot_vim/ftplugin/latex-suite/texviewer.vim')
-rw-r--r-- | dot_vim/ftplugin/latex-suite/texviewer.vim | 1052 |
1 files changed, 1052 insertions, 0 deletions
diff --git a/dot_vim/ftplugin/latex-suite/texviewer.vim b/dot_vim/ftplugin/latex-suite/texviewer.vim new file mode 100644 index 0000000..4dc8861 --- /dev/null +++ b/dot_vim/ftplugin/latex-suite/texviewer.vim @@ -0,0 +1,1052 @@ +" ============================================================================ +" File: texviewer.vim +" Author: Mikolaj Machowski +" Created: Sun Jan 26 06:00 PM 2003 +" Description: make a viewer for various purposes: \cite{, \ref{ +" License: Vim Charityware License +" Part of vim-latexSuite: http://vim-latex.sourceforge.net +" CVS: $Id: texviewer.vim 1004 2006-03-25 08:40:15Z srinathava $ +" ============================================================================ +" Tex_SetTexViewerMaps: sets maps for this ftplugin {{{ +function! Tex_SetTexViewerMaps() + inoremap <silent> <Plug>Tex_Completion <Esc>:call Tex_Complete("default","text")<CR> + if !hasmapto('<Plug>Tex_Completion', 'i') + if has('gui_running') + imap <buffer> <silent> <F9> <Plug>Tex_Completion + else + imap <buffer> <F9> <Plug>Tex_Completion + endif + endif +endfunction + +augroup LatexSuite + au LatexSuite User LatexSuiteFileType + \ call Tex_Debug('texviewer.vim: Catching LatexSuiteFileType event', 'view') | + \ call Tex_SetTexViewerMaps() +augroup END + +command -nargs=1 TLook call Tex_Complete(<q-args>, 'tex') +command -nargs=1 TLookAll call Tex_Complete(<q-args>, 'all') +command -nargs=1 TLookBib call Tex_Complete(<q-args>, 'bib') + +" }}} + +" ============================================================================== +" Main completion function +" ============================================================================== +" Tex_Complete: main function {{{ +" Description: +function! Tex_Complete(what, where) + + " Get info about current window and position of cursor in file + let s:winnum = winnr() + + " Change to the directory of the file being edited before running all the + " :grep commands. We will change back to the original directory after we + " finish with the grep. + let s:origdir = getcwd() + cd %:p:h + + let s:pos = line('.').' | normal! '.virtcol('.').'|' + + unlet! s:type + unlet! s:typeoption + + if Tex_GetVarValue('Tex_WriteBeforeCompletion') == 1 + wall + endif + + if a:where == "text" + " What to do after <F9> depending on context + let s:curfile = expand("%:p") + let s:curline = strpart(getline('.'), 0, col('.')) + let s:prefix = matchstr(s:curline, '.*{\zs.\{-}\(}\|$\)') + " a command is of the type + " \psfig[option=value]{figure=} + " Thus + " s:curline = '\psfig[option=value]{figure=' + " (with possibly some junk before \psfig) + " from which we need to extract + " s:type = 'psfig' + " s:typeoption = '[option=value]' + let pattern = '.*\\\(\w\{-}\)\(\[.\{-}\]\)\?{\(\S\+\)\?$' + if s:curline =~ pattern + let s:type = substitute(s:curline, pattern, '\1', 'e') + let s:typeoption = substitute(s:curline, pattern, '\2', 'e') + call Tex_Debug('Tex_Complete: s:type = '.s:type.', typeoption = '.s:typeoption, 'view') + endif + + if exists("s:type") && s:type =~ 'ref' + if Tex_GetVarValue('Tex_UseOutlineCompletion') == 1 + call Tex_Debug("Tex_Complete: using outline search method", "view") + call Tex_StartOutlineCompletion() + + elseif Tex_GetVarValue('Tex_UseSimpleLabelSearch') == 1 + call Tex_Debug("Tex_Complete: searching for \\labels in all .tex files in the present directory", "view") + call Tex_Debug("Tex_Complete: silent! grep! ".Tex_EscapeForGrep('\\label{'.s:prefix)." *.tex", 'view') + call Tex_Grep('\\label{'.s:prefix, '*.tex') + call <SID>Tex_SetupCWindow() + + elseif Tex_GetVarValue('Tex_ProjectSourceFiles') != '' + call Tex_Debug('Tex_Complete: searching for \\labels in all Tex_ProjectSourceFiles', 'view') + call Tex_CD(Tex_GetMainFileName(':p:h')) + call Tex_Grep('\\label{'.s:prefix, Tex_GetVarValue('Tex_ProjectSourceFiles')) + call <SID>Tex_SetupCWindow() + + else + call Tex_Debug("Tex_Complete: calling Tex_GrepHelper", "view") + silent! grep! ____HIGHLY_IMPROBABLE___ % + call Tex_GrepHelper(s:prefix, 'label') + call <SID>Tex_SetupCWindow() + endif + + redraw! + + elseif exists("s:type") && s:type =~ 'cite' + + let s:prefix = matchstr(s:prefix, '\([^,]\+,\)*\zs\([^,]\+\)\ze$') + call Tex_Debug(":Tex_Complete: using s:prefix = ".s:prefix, "view") + + if has('python') && Tex_GetVarValue('Tex_UsePython') + \ && Tex_GetVarValue('Tex_UseCiteCompletionVer2') == 1 + + call Tex_CD(s:origdir) + silent! call Tex_StartCiteCompletion() + + elseif Tex_GetVarValue('Tex_UseJabref') == 1 + + call Tex_CD(s:origdir) + let g:Remote_WaitingForCite = 1 + let citation = input('Enter citation from jabref (<enter> to leave blank): ') + let g:Remote_WaitingForCite = 0 + call Tex_CompleteWord(citation) + + else + " grep! nothing % + " does _not_ clear the search history contrary to what the + " help-docs say. This was expected. So use something improbable. + " TODO: Is there a way to clear the search-history w/o making a + " useless, inefficient search? + silent! grep! ____HIGHLY_IMPROBABLE___ % + if g:Tex_RememberCiteSearch && exists('s:citeSearchHistory') + call <SID>Tex_SetupCWindow(s:citeSearchHistory) + else + call Tex_GrepHelper(s:prefix, 'bib') + redraw! + call <SID>Tex_SetupCWindow() + endif + if g:Tex_RememberCiteSearch && &ft == 'qf' + let _a = @a + silent! normal! ggVG"ay + let s:citeSearchHistory = @a + let @a = _a + endif + endif + + elseif exists("s:type") && (s:type =~ 'includegraphics' || s:type == 'psfig') + call Tex_SetupFileCompletion( + \ '', + \ '^\.\\|\.tex$\\|\.bib$\\|\.bbl$\\|\.zip$\\|\.gz$', + \ 'noext') + + elseif exists("s:type") && s:type == 'bibliography' + call Tex_SetupFileCompletion( + \ '\.b..$', + \ '', + \ 'noext') + + elseif exists("s:type") && s:type =~ 'include\(only\)\=' + call Tex_SetupFileCompletion( + \ '\.t..$', + \ '', + \ 'noext') + + elseif exists("s:type") && s:type == 'input' + call Tex_SetupFileCompletion( + \ '', + \ '', + \ 'ext') + + elseif exists('s:type') && exists("g:Tex_completion_".s:type) + call <SID>Tex_CompleteRefCiteCustom('plugin_'.s:type) + + else + let s:word = expand('<cword>') + if s:word == '' + if col('.') == strlen(getline('.')) + startinsert! + return + else + normal! l + startinsert + return + endif + endif + call Tex_Debug("silent! grep! ".Tex_EscapeForGrep('\<'.s:word.'\>')." *.tex", 'view') + call Tex_Grep('\<'.s:word.'\>', '*.tex') + + call <SID>Tex_SetupCWindow() + endif + + elseif a:where == 'tex' + " Process :TLook command + call Tex_Grep(a:what, "*.tex") + call <SID>Tex_SetupCWindow() + + elseif a:where == 'bib' + " Process :TLookBib command + call Tex_Grep(a:what, "*.bib") + call Tex_Grepadd(a:what, "*.bbl") + call <SID>Tex_SetupCWindow() + + elseif a:where == 'all' + " Process :TLookAll command + call Tex_Grep(a:what, "*") + call <SID>Tex_SetupCWindow() + endif + +endfunction +" }}} +" Tex_CompleteWord: inserts a word at the chosen location {{{ +" Description: This function is meant to be called when the user press +" ``<enter>`` in one of the [Error List] windows which shows the list of +" matches. completeword is the rest of the word which needs to be inserted. +function! Tex_CompleteWord(completeword) + exe s:pos + + " Complete word, check if add closing } + exe 'normal! a'.a:completeword."\<Esc>" + + if getline('.')[col('.')-1] !~ '{' && getline('.')[col('.')] !~ '}' + exe "normal! a}\<Esc>" + endif + + " Return to Insert mode + if col('.') == strlen(getline('.')) + startinsert! + else + normal! l + startinsert + endif +endfunction " }}} + +" ============================================================================== +" File name completion helper functons +" ============================================================================== +" Tex_SetupFileCompletion: {{{ +" Description: +function! Tex_SetupFileCompletion(accept, reject, ext) + call FB_SetVar('FB_AllowRegexp', a:accept) + call FB_SetVar('FB_RejectRegexp', a:reject) + call FB_SetVar('FB_CallBackFunction', 'Tex_CompleteFileName') + call FB_SetVar('FB_CallBackFunctionArgs', '"'.a:ext.'"') + + call FB_OpenFileBrowser('.') +endfunction " }}} +" Tex_CompleteFileName: {{{ +" Description: +function! Tex_CompleteFileName(filename, ext) + call Tex_Debug('+Tex_CompleteFileName: getting filename '.a:filename, 'view') + + if a:ext == 'noext' + let completeword = fnamemodify(a:filename, ':r') + endif + let completeword = Tex_RelPath(completeword, Tex_GetMainFileName(':p:h')) + + call Tex_Debug(":Tex_CompleteFileName: completing with ".completeword, "view") + call Tex_CompleteWord(completeword) +endfunction " }}} +" Tex_Common: common part of strings {{{ +function! s:Tex_Common(path1, path2) + " Assume the caller handles 'ignorecase' + if a:path1 == a:path2 + return a:path1 + endif + let n = 0 + while a:path1[n] == a:path2[n] + let n = n+1 + endwhile + return strpart(a:path1, 0, n) +endfunction " }}} +" Tex_NormalizePath: {{{ +" Description: +function! Tex_NormalizePath(path) + let retpath = a:path + if has("win32") || has("win16") || has("dos32") || has("dos16") + let retpath = substitute(retpath, '\\', '/', 'ge') + endif + if isdirectory(retpath) && retpath !~ '/$' + let retpath = retpath.'/' + endif + return retpath +endfunction " }}} +" Tex_RelPath: ultimate file name {{{ +function! Tex_RelPath(explfilename,texfilename) + let path1 = Tex_NormalizePath(a:explfilename) + let path2 = Tex_NormalizePath(a:texfilename) + + let n = matchend(<SID>Tex_Common(path1, path2), '.*/') + let path1 = strpart(path1, n) + let path2 = strpart(path2, n) + if path2 !~ '/' + let subrelpath = '' + else + let subrelpath = substitute(path2, '[^/]\{-}/', '../', 'ge') + let subrelpath = substitute(subrelpath, '[^/]*$', '', 'ge') + endif + let relpath = subrelpath.path1 + return escape(Tex_NormalizePath(relpath), ' ') +endfunction " }}} + +" ============================================================================== +" Helper functions for dealing with the 'quickfix' and 'preview' windows. +" ============================================================================== +" Tex_SetupCWindow: set maps and local settings for cwindow {{{ +" Description: Set local maps jkJKq<cr> for cwindow. Also size and basic +" settings +" +function! s:Tex_SetupCWindow(...) + call Tex_Debug('+Tex_SetupCWindow', 'view') + cclose + exe 'copen '. g:Tex_ViewerCwindowHeight + " If called with an argument, it means we want to re-use some search + " history from last time. Therefore, just paste it here and proceed. + if a:0 == 1 + set modifiable + % d _ + silent! 0put!=a:1 + $ d _ + endif + setlocal nonumber + setlocal nowrap + + let s:scrollOffVal = &scrolloff + call <SID>Tex_SyncPreviewWindow() + + " If everything went well, then we should be situated in the quickfix + " window. If there were problems, (no matches etc), then we will not be. + " Therefore return. + if &ft != 'qf' + call Tex_Debug('not in quickfix window, quitting', 'view') + return + endif + + nnoremap <buffer> <silent> j j:call <SID>Tex_SyncPreviewWindow()<CR> + nnoremap <buffer> <silent> k k:call <SID>Tex_SyncPreviewWindow()<CR> + nnoremap <buffer> <silent> <up> <up>:call <SID>Tex_SyncPreviewWindow()<CR> + nnoremap <buffer> <silent> <down> <down>:call <SID>Tex_SyncPreviewWindow()<CR> + + " Change behaviour of <cr> only for 'ref' and 'cite' context. + if exists("s:type") && s:type =~ 'ref\|cite' + exec 'nnoremap <buffer> <silent> <cr> ' + \ .':set scrolloff='.s:scrollOffVal.'<CR>' + \ .':cd '.s:origdir.'<CR>' + \ .':silent! call <SID>Tex_CompleteRefCiteCustom("'.s:type.'")<CR>' + + else + " In other contexts jump to place described in cwindow and close small + " windows + exec 'nnoremap <buffer> <silent> <cr> ' + \ .':set scrolloff='.s:scrollOffVal.'<CR>' + \ .':cd '.s:origdir.'<CR>' + \ .':call <SID>Tex_GoToLocation()<cr>' + + endif + + " Scroll the preview window while in the quickfix window + nnoremap <buffer> <silent> J :wincmd j<cr><c-e>:wincmd k<cr> + nnoremap <buffer> <silent> K :wincmd j<cr><c-y>:wincmd k<cr> + + " Exit the quickfix window without doing anything. + exe 'nnoremap <buffer> <silent> q ' + \ .':set scrolloff='.s:scrollOffVal.'<CR>' + \ .':cd '.s:origdir.'<CR>' + \ .':call Tex_CloseSmallWindows()<CR>' + +endfunction " }}} +" Tex_CompleteRefCiteCustom: complete/insert name for current item {{{ +" Description: handle completion of items depending on current context +" +function! s:Tex_CompleteRefCiteCustom(type) + + if a:type =~ 'cite' + if getline('.') =~ '\\bibitem{' + let bibkey = matchstr(getline('.'), '\\bibitem{\zs.\{-}\ze}') + else + let bibkey = matchstr(getline('.'), '{\zs.\{-}\ze\(,\|$\)') + endif + let completeword = strpart(bibkey, strlen(s:prefix)) + + elseif a:type =~ 'ref' + let label = matchstr(getline('.'), '\\label{\zs.\{-}\ze}') + let completeword = strpart(label, strlen(s:prefix)) + + elseif a:type =~ '^plugin_' + let type = substitute(a:type, '^plugin_', '', '') + let completeword = <SID>Tex_DoCompletion(type) + + endif + + call Tex_CloseSmallWindows() + call Tex_Debug(":Tex_CompleteRefCiteCustom: completing with ".completeword, "view") + call Tex_CompleteWord(completeword) +endfunction " }}} +" Tex_SyncPreviewWindow: synchronize quickfix and preview window {{{ +" Description: Usually quickfix engine takes care about most of these things +" but we discard it for better control of events. +" +function! s:Tex_SyncPreviewWindow() + call Tex_Debug('+Tex_SyncPreviewWindow', 'view') + + let viewfile = matchstr(getline('.'), '^\f*\ze|\d') + let viewline = matchstr(getline('.'), '|\zs\d\+\ze') + + " Hilight current line in cwindow + " Normally hightlighting is done with quickfix engine but we use something + " different and have to do it separately + syntax clear + runtime syntax/qf.vim + exe 'syn match vTodo /\%'. line('.') .'l.*/' + hi link vTodo Todo + + " Close preview window and open it again in new place + pclose + exe 'silent! bot pedit +'.viewline.' '.viewfile + + " Vanilla 6.1 has bug. This additional setting of cwindow height prevents + " resizing of this window + exe g:Tex_ViewerCwindowHeight.' wincmd _' + + " Handle situation if there is no item beginning with s:prefix. + " Unfortunately, because we know it late we have to close everything and + " return as in complete process + if v:errmsg =~ 'E32\>' + exe s:winnum.' wincmd w' + pclose! + cclose + if exists("s:prefix") + echomsg 'No bibkey, label or word beginning with "'.s:prefix.'"' + endif + if col('.') == strlen(getline('.')) + startinsert! + else + normal! l + startinsert + endif + let v:errmsg = '' + call Tex_Debug('Tex_SyncPreviewWindow: got error E32, no matches found, quitting', 'view') + return 0 + endif + + " Move to preview window. Really is it under cwindow? + wincmd j + + " Settings of preview window + exe g:Tex_ViewerPreviewHeight.' wincmd _' + setlocal nofoldenable + + if exists('s:type') && s:type =~ 'cite' + " In cite context place bibkey at the top of preview window. + setlocal scrolloff=0 + normal! zt + else + " In other contexts in the middle. Highlight this line? + setlocal scrolloff=100 + normal! z. + endif + + " Return to cwindow + wincmd p + +endfunction " }}} +" Tex_CloseSmallWindows: {{{ +" Description: +" +function! Tex_CloseSmallWindows() + exe s:winnum.' wincmd w' + pclose! + cclose + exe s:pos +endfunction " }}} +" Tex_GoToLocation: Go to chosen location {{{ +" Description: Get number of current line and go to this number +" +function! s:Tex_GoToLocation() + pclose! + let errmsg = v:errmsg + let v:errmsg = '' + exe 'silent! cc ' . line('.') + " If the current buffer is modified, then split + if v:errmsg =~ '^E37:' + split + exe 'silent! cc ' . line('.') + endif + cclose + let v:errmsg = errmsg +endfunction " }}} + +" ============================================================================== +" Functions for finding \\label's or \\bibitem's in the main file. +" ============================================================================== +" Tex_GrepHelper: grep main filename for \\bibitem's or \\label's {{{ +" Description: +function! Tex_GrepHelper(prefix, what) + let _path = &path + let _suffixesadd = &suffixesadd + let _hidden = &hidden + + let mainfname = Tex_GetMainFileName(':p') + " If we are already editing the file, then use :split without any + " arguments so it works even if the file is modified. + " FIXME: If mainfname is being presently edited in another window and + " is 'modified', then the second split statement will not work. + " We will need to travel to that window and back. + if mainfname == expand('%:p') + split + else + exec 'split '.Tex_EscapeSpaces(mainfname) + endif + + let pos = line('.').'| normal! '.virtcol('.').'|' + if a:what =~ 'bib' + call Tex_ScanFileForCite(a:prefix) + else + call Tex_ScanFileForLabels(a:prefix) + endif + exec pos + + q + let &path = _path + let &suffixesadd = _suffixesadd + +endfunction " }}} +" Tex_ScanFileForCite: search for \bibitem's in .bib or .bbl or tex files {{{ +" Description: +" Search for bibliographic entries in the presently edited file in the +" following manner: +" 1. First see if the file has a \bibliography command. +" If YES: +" 1. If a .bib file corresponding to the \bibliography command can be +" found, then search for '@.*'.a:prefix inside it. +" 2. Otherwise, if a .bbl file corresponding to the \bibliography command +" can be found, then search for '\bibitem'.a:prefix inside it. +" 2. Next see if the file has a \thebibliography environment +" If YES: +" 1. Search for '\bibitem'.a:prefix in this file. +" +" If neither a \bibliography or \begin{thebibliography} are found, then repeat +" steps 1 and 2 for every file \input'ed into this file. Abort any searching +" as soon as the first \bibliography or \begin{thebibliography} is found. +function! Tex_ScanFileForCite(prefix) + call Tex_Debug('+Tex_ScanFileForCite: searching for bibkeys in '.bufname('%').' (buffer #'.bufnr('%').')', 'view') + let presBufNum = bufnr('%') + + let foundCiteFile = 0 + " First find out if this file has a \bibliography command in it. If so, + " assume that this is the only file in the project which defines a + " bibliography. + if search('\\\(no\)\?bibliography{', 'w') + call Tex_Debug('Tex_ScanFileForCite: found bibliography command in '.bufname('%'), 'view') + " convey that we have found a bibliography command. we do not need to + " proceed any further. + let foundCiteFile = 1 + + " extract the bibliography filenames from the command. + let bibnames = matchstr(getline('.'), '\\\(no\)\?bibliography{\zs.\{-}\ze}') + let bibnames = substitute(bibnames, '\s', '', 'g') + + call Tex_Debug('trying to search through ['.bibnames.']', 'view') + + let &path = '.,'.g:Tex_BIBINPUTS + + let i = 1 + while 1 + let bibname = Tex_Strntok(bibnames, ',', i) + if bibname == '' + break + endif + + " first try to find if a .bib file exists. If so do not search in + " the corresponding .bbl file. (because the .bbl file will most + " probly be generated automatically from the .bib file with + " bibtex). + + let fname = Tex_FindFile(bibname, '.,'.g:Tex_BIBINPUTS, '.bib') + if fname != '' + call Tex_Debug('finding .bib file ['.bufname('%').']', 'view') + exec 'split '.Tex_EscapeSpaces(fname) + call Tex_Grepadd('@.*{'.a:prefix, "%") + q + else + let fname = Tex_FindFile(bibname, '.,'.g:Tex_BIBINPUTS, '.bbl') + if fname != '' + exec 'split '.Tex_EscapeSpaces(fname) + call Tex_Debug('finding .bbl file ['.bufname('.').']', 'view') + call Tex_Grepadd('\\bibitem{'.a:prefix, "%") + q + endif + endif + + let i = i + 1 + endwhile + + if foundCiteFile + return 1 + endif + endif + + " If we have a thebibliography environment, then again assume that this is + " the only file which defines the bib-keys. Aand convey this information + " upwards by returning 1. + if search('^\s*\\begin{thebibliography}', 'w') + call Tex_Debug('got a thebibliography environment in '.bufname('%'), 'view') + + let foundCiteFile = 1 + + split + lcd %:p:h + call Tex_Debug("silent! grepadd! ".Tex_EscapeForGrep('\\bibitem{'.a:prefix)." %", 'view') + call Tex_Grepadd('\\bibitem{'.a:prefix, "%") + q + + return 1 + endif + + " If we have not found any \bibliography or \thebibliography environment + " in this file, search for these environments in all the files which this + " file includes. + + exec 0 + let wrap = 'w' + while search('^\s*\\\(input\|include\)', wrap) + let wrap = 'W' + + let filename = matchstr(getline('.'), '\\\(input\|include\){\zs.\{-}\ze}') + + let foundfile = Tex_FindFile(filename, '.,'.g:Tex_TEXINPUTS, '.tex') + if foundfile != '' + exec 'split '.Tex_EscapeSpaces(foundfile) + call Tex_Debug('scanning recursively in ['.foundfile.']', 'view') + let foundCiteFile = Tex_ScanFileForCite(a:prefix) + q + endif + + if foundCiteFile + return 1 + endif + endwhile + + + return 0 +endfunction " }}} +" Tex_ScanFileForLabels: greps present file and included files for \\label's {{{ +" Description: +" Grep the presently edited file for \\label's. If the present file \include's +" or \input's other files, then recursively scan those as well, i.e we support +" arbitrary levels of \input'ed-ness. +function! Tex_ScanFileForLabels(prefix) + call Tex_Debug("+Tex_ScanFileForLabels: grepping in file [".bufname('%')."]", "view") + + lcd %:p:h + call Tex_Grepadd('\\label{'.a:prefix, "%") + + " Then recursively grep for all \include'd or \input'ed files. + exec 0 + let wrap = 'w' + while search('^\s*\\\(input\|include\)', wrap) + let wrap = 'W' + + let filename = matchstr(getline('.'), '\\\(input\|include\){\zs.\{-}\ze}') + let foundfile = Tex_FindFile(filename, '.,'.Tex_TEXINPUTS, '.tex') + if foundfile != '' + exec 'split '.Tex_EscapeSpaces(foundfile) + call Tex_Debug('Tex_ScanFileForLabels: scanning recursively in ['.foundfile.']', 'view') + call Tex_ScanFileForLabels(a:prefix) + q + endif + endwhile + +endfunction " }}} + +" ============================================================================== +" Functions for custom command completion +" ============================================================================== +" Tex_completion_{var}: similar variables can be set in package files {{{ +let g:Tex_completion_bibliographystyle = 'abbr,alpha,plain,unsrt' +let g:Tex_completion_addtocontents = 'lof}{,lot}{,toc}{' +let g:Tex_completion_addcontentsline = 'lof}{figure}{,lot}{table}{,toc}{chapter}{,toc}{part}{,'. + \ 'toc}{section}{,toc}{subsection}{,toc}{paragraph}{,'. + \ 'toc}{subparagraph}{' +" }}} +" Tex_PromptForCompletion: prompts for a completion {{{ +" Description: +function! s:Tex_PromptForCompletion(texcommand,ask) + + let common_completion_prompt = + \ Tex_CreatePrompt(g:Tex_completion_{a:texcommand}, 2, ',') . "\n" . + \ 'Enter number or completion: ' + + let inp = input(a:ask."\n".common_completion_prompt) + if inp =~ '^[0-9]\+$' + let completion = Tex_Strntok(g:Tex_completion_{a:texcommand}, ',', inp) + else + let completion = inp + endif + + return completion +endfunction " }}} +" Tex_DoCompletion: fast insertion of completion {{{ +" Description: +" +function! s:Tex_DoCompletion(texcommand) + let completion = <SID>Tex_PromptForCompletion(a:texcommand, 'Choose a completion to insert: ') + if completion != '' + return completion + else + return '' + endif +endfunction " }}} + +" ============================================================================== +" Functions for presenting an outlined version for completion +" ============================================================================== +" Tex_StartOutlineCompletion: sets up an outline window {{{ + +" get the place where this plugin resides for setting cpt and dict options. +" these lines need to be outside the function. +let s:path = expand('<sfile>:p:h') +if has('python') && Tex_GetVarValue('Tex_UsePython') + python import sys, re + exec "python sys.path += [r'". s:path . "']" + python import outline +endif + +function! Tex_StartOutlineCompletion() + let mainfname = Tex_GetMainFileName(':p') + + " open the buffer + let _report = &report + let _cmdheight=&cmdheight + let _lazyredraw = &lazyredraw + set report=1000 + set cmdheight=1 + set lazyredraw + + bot split __OUTLINE__ + exec Tex_GetVarValue('Tex_OutlineWindowHeight', 15).' wincmd _' + + setlocal modifiable + setlocal noswapfile + setlocal buftype=nowrite + setlocal bufhidden=delete + setlocal nowrap + setlocal foldmethod=marker + setlocal foldmarker=<<<,>>> + + " delete everything in it to the blackhole + % d _ + + if has('python') && Tex_GetVarValue('Tex_UsePython') + exec 'python retval = outline.main(' + \. 'r"' . fnamemodify(mainfname, ':p') . '", ' + \. 'r"' . s:prefix . '")' + + " transfer variable from python to a local variable. + python vim.command("""let retval = "%s" """ % re.sub(r'"|\\', r'\\\g<0>', retval)) + + 0put!=retval + else + exec '0r!'.s:path.'/outline.py '.mainfname.' '.s:prefix + endif + + 0 + + call Tex_SetupOutlineSyntax() + + exec 'nnoremap <buffer> <cr> ' + \ .':cd '.s:origdir.'<CR>' + \ .':call Tex_FinishOutlineCompletion()<CR>' + exec 'nnoremap <buffer> q ' + \ .':cd '.s:origdir.'<CR>' + \ .':close<CR>' + + " once the buffer is initialized, go back to the original settings. + setlocal nomodifiable + setlocal nomodified + let &report = _report + let &cmdheight = _cmdheight + let &lazyredraw = _lazyredraw + +endfunction " }}} +" Tex_SetupOutlineSyntax: sets up the syntax items for the outline {{{ +" Description: +function! Tex_SetupOutlineSyntax() + syn match outlineFileName "<\f\+>$" contained + syn match foldMarkers "<<<\d$" contained + syn match firstSemiColon '^:' contained + syn match firstAngle '^>' contained + + syn match sectionNames '\(\d\.\)\+ .*' contains=foldMarkers + syn match previousLine '^:.*' contains=firstSemiColon + syn match labelLine '^>.*' contains=firstAngle,outlineFileName + + hi def link outlineFileName Ignore + hi def link foldMarkers Ignore + hi def link firstSemiColon Ignore + hi def link firstAngle Ignore + + hi def link sectionNames Type + hi def link previousLine Special + hi def link labelLine Comment +endfunction " }}} +" Tex_FinishOutlineCompletion: inserts the reference back in the text {{{ +function! Tex_FinishOutlineCompletion() + if getline('.') !~ '^[>:]' + return + endif + + if getline('.') =~ '^>' + let ref_complete = matchstr(getline('.'), '^>\s\+\zs\S\+\ze') + elseif getline('.') =~ '^:' + let ref_complete = matchstr(getline(line('.')-1), '^>\s\+\zs\S\+\ze') + endif + + let ref_remaining = strpart(ref_complete, strlen(s:prefix)) + close + call Tex_CompleteWord(ref_remaining) +endfunction " }}} + +" ============================================================================== +" Functions for presenting a nicer list of bibtex entries +" ============================================================================== +" Tex_FindBibFiles: finds all .bib files used by the main file {{{ +" Description: +function! Tex_FindBibFiles() + + let mainfname = Tex_GetMainFileName(':p') + wincmd n + exec 'silent! e '.mainfname + + if search('\\\(no\)\?bibliography{', 'w') + + call Tex_Debug('Tex_FindBibFiles: found bibliography command in '.bufname('%'), 'view') + + " extract the bibliography filenames from the command. + let bibnames = matchstr(getline('.'), '\\\(no\)\?bibliography{\zs.\{-}\ze}') + let bibnames = substitute(bibnames, '\s', '', 'g') + + call Tex_Debug(':Tex_FindBibFiles: trying to search through ['.bibnames.']', 'view') + + let bibfiles = '' + let i = 1 + while 1 + let bibname = Tex_Strntok(bibnames, ',', i) + if bibname == '' + break + endif + let fname = Tex_FindFile(bibname, '.,'.g:Tex_BIBINPUTS, '.bib') + if fname != '' + let bibfiles = bibfiles.fname."\n" + endif + let i = i + 1 + endwhile + + call Tex_Debug(":Tex_FindBibFiles: returning [".bibfiles."]", "view") + q + return bibfiles + + else + q + return '' + endif + +endfunction " }}} +" Tex_StartBibtexOutline: sets up an outline window {{{ + +" get the place where this plugin resides for setting cpt and dict options. +" these lines need to be outside the function. +if has('python') && Tex_GetVarValue('Tex_UsePython') + python import sys, re + exec "python sys.path += [r'". s:path . "']" + python import bibtools +endif + +function! Tex_StartCiteCompletion() + let bibfiles = Tex_FindBibFiles() + if bibfiles !~ '\S' + echohl WarningMsg + echomsg 'No bibfiles found! Sorry' + echohl None + return + endif + + bot split __OUTLINE__ + exec Tex_GetVarValue('Tex_OutlineWindowHeight', 15).' wincmd _' + + exec 'python Tex_BibFile = bibtools.BibFile("""'.bibfiles.'""")' + exec 'python Tex_BibFile.addfilter("key ^'.s:prefix.'")' + call Tex_DisplayBibList() + + nnoremap <Plug>Tex_JumpToNextBibEntry :call search('^\S.*\]$', 'W')<CR>:call Tex_EchoBibShortcuts()<CR>z. + nnoremap <Plug>Tex_JumpToPrevBibEntry :call search('^\S.*\]$', 'bW')<CR>:call Tex_EchoBibShortcuts()<CR>z. + nnoremap <Plug>Tex_FilterBibEntries :call Tex_HandleBibShortcuts('filter')<CR> + nnoremap <Plug>Tex_RemoveBibFilters :call Tex_HandleBibShortcuts('remove_filters')<CR> + nnoremap <Plug>Tex_SortBibEntries :call Tex_HandleBibShortcuts('sort')<CR> + nnoremap <Plug>Tex_CompleteCiteEntry :call Tex_CompleteCiteEntry()<CR> + + nmap <buffer> <silent> n <Plug>Tex_JumpToNextBibEntry + nmap <buffer> <silent> p <Plug>Tex_JumpToPrevBibEntry + nmap <buffer> <silent> f <Plug>Tex_FilterBibEntries + nmap <buffer> <silent> s <Plug>Tex_SortBibEntries + nmap <buffer> <silent> a <Plug>Tex_RemoveBibFilters + nmap <buffer> <silent> q :close<CR> + nmap <buffer> <silent> <CR> <Plug>Tex_CompleteCiteEntry + +endfunction " }}} +" Tex_DisplayBibList: displays the list of bibtex entries {{{ +" Description: +function! Tex_DisplayBibList() + " open the buffer + let _report = &report + let _cmdheight=&cmdheight + let _lazyredraw = &lazyredraw + set report=1000 + set cmdheight=1 + set lazyredraw + + setlocal modifiable + setlocal noswapfile + setlocal buftype=nowrite + setlocal bufhidden=delete + setlocal nowrap + setlocal foldmethod=marker + setlocal foldmarker=<<<,>>> + + + " delete everything in it to the blackhole + % d _ + + exec 'python Tex_CurBuf = vim.current.buffer' + exec 'python Tex_CurBuf[:] = str(Tex_BibFile).splitlines()' + + call Tex_SetupBibSyntax() + + 0 + call Tex_EchoBibShortcuts() + + " once the buffer is initialized, go back to the original settings. + setlocal nomodifiable + setlocal nomodified + let &report = _report + let &cmdheight = _cmdheight + let &lazyredraw = _lazyredraw + +endfunction " }}} +" Tex_EchoBibShortcuts: echos all the shortcuts in the status line {{{ +" Description: +function! Tex_EchoBibShortcuts() + echomsg '(a) all (f) filter (s) sort (n) next (p) previous (q) quit (<CR>) choose' +endfunction " }}} +" Tex_SetupBibSyntax: sets up the syntax items for the outline {{{ +" Description: +function! Tex_SetupBibSyntax() + syn match BibTitleHeader "^TI" contained + syn match BibAuthorHeader "^AU" contained + syn match BibLocationHeader "^IN" contained + syn match BibMiscHeader "^MI" contained + + syn match BibKeyLine '^\S.*\]$' contains=BibKey + syn match BibTitle "^TI .*" contains=BibTitleHeader + syn match BibAuthor "^AU .*" contains=BibAuthorHeader + syn match BibLocation "^IN .*" contains=BibLocationHeader + syn match BibMisc "^MI .*" contains=BibMiscHeader + + hi def link BibTitleHeader Ignore + hi def link BibAuthorHeader Ignore + hi def link BibLocationHeader Ignore + hi def link BibMiscHeader Ignore + + hi def link BibKeyLine Visual + hi def link BibTitle Type + hi def link BibAuthor Special + hi def link BibLocation Comment + hi def link BibMisc Comment +endfunction " }}} +" Tex_HandleBibShortcuts: handles user keypresses {{{ +" Description: +function! Tex_HandleBibShortcuts(command) + + if a:command == 'filter' || a:command == 'sort' + + let fieldprompt = + \ "Field acronyms: (`:let g:Tex_EchoBibFields = 0` to avoid this message)\n" . + \ " [t] title [a] author [b] booktitle \n" . + \ " [j] journal [y] year [p] bibtype \n" . + \ " (you can also enter the complete field name) \n" + + let fieldprompt = Tex_GetVarValue('Tex_BibFieldPrompt', fieldprompt) + + if Tex_GetVarValue('Tex_EchoBibFields', 1) == 1 + echo fieldprompt + endif + + let inp = input('Enter '.a:command.' criterion [field<space>value]: ') + if inp !~ '\v^\S+\s+\S.*' + echohl WarningMsg + echomsg 'Invalid filter specification. Use "field<space>value"' + echohl None + return + endif + + if inp != '' + " If the field is specified as a single character, then replace + " it with the corresponding 'full form'. + if inp =~ '^[a-z]\>' + if Tex_GetVarValue('Tex_BibAcronym_'.inp[0]) != '' + let inp = substitute(inp, '.', Tex_GetVarValue('Tex_BibAcronym_'.inp[0]), '') + elseif fieldprompt =~ '\['.inp[0].'\]' + let full = matchstr(fieldprompt, '\['.inp[0].'\] \zs\w\+\ze') + let inp = substitute(inp, '.', full, '') + endif + endif + call Tex_Debug(":Tex_HandleBibShortcuts: using inp = [".inp."]", "view") + if a:command == 'filter' + exec 'python Tex_BibFile.addfilter("'.inp.'")' + elseif a:command == 'sort' + exec "python Tex_BibFile.addsortfield(\"".inp."\")" + exec 'python Tex_BibFile.sort()' + endif + silent! call Tex_DisplayBibList() + endif + + elseif a:command == 'remove_filters' + + exec 'python Tex_BibFile.rmfilters()' + exec 'python Tex_BibFile.addfilter("key ^'.s:prefix.'")' + call Tex_DisplayBibList() + + endif + +endfunction " }}} +" Tex_CompleteCiteEntry: completes cite entry {{{ +" Description: +function! Tex_CompleteCiteEntry() + normal! 0 + call search('\[\S\+\]$', 'W') + if getline('.') !~ '\[\S\+\]$' + call search('\[\S\+\]$', 'bW') + endif + + if getline('.') !~ '\[\S\+\]$' + return + endif + + let ref = matchstr(getline('.'), '\[\zs\S\+\ze\]$') + close + call Tex_Debug(":Tex_CompleteCiteEntry: completing with ".ref, "view") + call Tex_CompleteWord(strpart(ref, strlen(s:prefix))) +endfunction " }}} + +com! -nargs=0 TClearCiteHist unlet! s:citeSearchHistory + +" vim:fdm=marker:nowrap:noet:ff=unix:ts=4:sw=4 |