" Vimball Archiver by Charles E. Campbell, Jr., Ph.D. UseVimball finish autoload/atplib.vim [[[1 6167 " Title: Vim library for ATP filetype plugin. " Author: Marcin Szamotulski " Email: mszamot [AT] gmail [DOT] com " Note: This file is a part of Automatic Tex Plugin for Vim. " URL: https://launchpad.net/automatictexplugin " Language: tex " Source ATPRC File: function! atplib#ReadATPRC() "{{{ if ( has("unix") || has("max") || has("macunix") ) " Note: in $HOME/.atprc file the user can set all the local buffer " variables without using autocommands " " Note: it must be sourced at the begining because some options handle " how atp will load (for example if we load history or not) " It also should be run at the end if the user defines mapping that " should be overwrite the ATP settings (this is done via " autocommand). let atprc_file=split(globpath($HOME, '.atprc.vim', 1), "\n")[0] if !filereadable(atprc_file) let atprc_file = get(split(globpath(&rtp, "**/ftplugin/ATP_files/atprc.vim"), '\n'), 0, "") endif if filereadable(atprc_file) execute 'source ' . fnameescape(atprc_file) endif else let atprc_file = get(split(globpath(&rtp, "**/ftplugin/ATP_files/atprc.vim"), '\n'), 0, "") if filereadable(atprc_file) execute 'source ' . fnameescape(atprc_file) endif endif endfunction "}}} " Kill: function! atplib#KillPIDs(pids,...) "{{{ if len(a:pids) == 0 && a:0 == 0 return endif python << END import os, signal from signal import SIGKILL pids=vim.eval("a:pids") for pid in pids: try: os.kill(int(pid),SIGKILL) except OSError: pass END endfunction "}}} " Write: function! atplib#write(...) "{{{ let backup = &backup let writebackup = &writebackup let project = b:atp_ProjectScript " In this way lastchange plugin will work better (?): " let eventignore = &eventignore " setl eventigonre +=BufWritePre " Disable WriteProjectScript let b:atp_ProjectScript = 0 set nobackup set nowritebackup if a:0 > 0 && a:1 == "silent" silent! update else update endif let b:atp_ProjectScript = project let &backup = backup let &writebackup = writebackup " let &eventignore = eventignore endfunction "}}} " Log: function! atplib#Log(file, string, ...) "{{{1 if finddir(g:atp_TempDir, "/") == "" call mkdir(g:atp_TempDir, "p", 0700) endif if a:0 >= 1 call delete(g:atp_TempDir."/".a:file) else exe "redir >> ".g:atp_TempDir."/".a:file silent echo a:string redir END endif endfunction "}}}1 "Make g:atp_TempDir, where log files are stored. "{{{1 function! atplib#TempDir() " Return temporary directory, unique for each user. if has("python") function! ATP_SetTempDir(tmp) let g:atp_TempDir=a:tmp endfunction python << END import vim, tempfile, os USER=os.getenv("USER") tmp=tempfile.mkdtemp(suffix="", prefix="atp_") vim.eval("ATP_SetTempDir('"+tmp+"')") END delfunction ATP_SetTempDir else let g:atp_TempDir=substitute(tempname(), '\d\+$', "atp_debug", '') call mkdir(g:atp_TempDir, "p", 0700) endif endfunction "}}}1 " Outdir: append to '/' to b:atp_OutDir if it is not present. function! atplib#outdir() "{{{1 if has("win16") || has("win32") || has("win64") || has("win95") if b:atp_OutDir !~ "\/$" let b:atp_OutDir=b:atp_OutDir . "\\" endif else if b:atp_OutDir !~ "\/$" let b:atp_OutDir=b:atp_OutDir . "/" endif endif return b:atp_OutDir endfunction "}}}1 " Return {path} relative to {rel}, if not under {rel} return {path} function! atplib#RelativePath(path, rel) "{{{1 let current_dir = getcwd() exe "lcd " . fnameescape(a:rel) let rel_path = fnamemodify(a:path, ':.') exe "lcd " . fnameescape(current_dir) return rel_path endfunction "}}}1 " Return fullpath function! atplib#FullPath(file_name) "{{{1 let cwd = getcwd() if a:file_name =~ '^\s*\/' let file_path = a:file_name elseif exists("b:atp_ProjectDir") exe "lcd " . fnameescape(b:atp_ProjectDir) let file_path = fnamemodify(a:file_name, ":p") exe "lcd " . fnameescape(cwd) else let file_path = fnamemodify(a:file_name, ":p") endif return file_path endfunction "}}}1 " Table: "{{{ atplibTable, atplib#FormatListinColumns, atplib#PrintTable function! atplib#Table(list, spaces) " take a list of lists and make a list which is nicely formated (to echo it) " spaces = list of spaces between columns. "maximal length of columns: let max_list=[] let new_list=[] for i in range(len(a:list[0])) let max=max(map(deepcopy(a:list), "len(v:val[i])")) call add(max_list, max) endfor for row in a:list let new_row=[] let i=0 for el in row let new_el=el.join(map(range(max([0,max_list[i]-len(el)+get(a:spaces,i,0)])), "' '"), "") call add(new_row, new_el) let i+=1 endfor call add(new_list, new_row) endfor return map(new_list, "join(v:val, '')") endfunction function! atplib#FormatListinColumns(list,s) " take a list and reformat it into many columns " a:s is the number of spaces between columns " for example of usage see atplib#PrintTable let max_len=max(map(copy(a:list), 'len(v:val)')) let new_list=[] let k=&l:columns/(max_len+a:s) let len=len(a:list) let column_len=len/k for i in range(0, column_len) let entry=[] for j in range(0,k) call add(entry, get(a:list, i+j*(column_len+1), "")) endfor call add(new_list,entry) endfor return new_list endfunction " Take list format it with atplib#FormatListinColumns and then with " atplib#Table (which makes columns of equal width) function! atplib#PrintTable(list, spaces) " a:list - list to print " a:spaces - nr of spaces between columns let list = atplib#FormatListinColumns(a:list, a:spaces) let nr_of_columns = max(map(copy(list), 'len(v:val)')) let spaces_list = ( nr_of_columns == 1 ? [0] : map(range(1,nr_of_columns-1), 'a:spaces') ) return atplib#Table(list, spaces_list) endfunction "}}} " QFLength "{{{ function! atplib#qflength() let lines = 1 " i.e. open with one more line than needed. for qf in getqflist() let text=substitute(qf['text'], '\_s\+', ' ', 'g') let lines+=(len(text))/&l:columns+1 endfor return lines endfunction "}}} function! atplib#Let(varname, varvalue) exe "let ".substitute(string(a:varname), "'", "", "g")."=".substitute(string(a:varvalue), "''\\@!", "", "g") endfunction " IMap Functions: " {{{ " These maps extend ideas from TeX_9 plugin: " With a:1 = "!" (bang) remove texMathZoneT (tikzpicture from MathZones). function! atplib#IsInMath(...) let line = a:0 >= 2 ? a:2 : line(".") let col = a:0 >= 3 ? a:3 : col(".")-1 if a:0 > 0 && a:1 == "!" let atp_MathZones=filter(copy(g:atp_MathZones), "v:val != 'texMathZoneT'") else let atp_MathZones=copy(g:atp_MathZones) endif call filter(atp_MathZones, 'v:val !~ ''\''') if atplib#CheckSyntaxGroups(['texMathZoneV', 'texMathZoneW', 'texMathZoneX', 'texMathZoneY']) return 1 else return atplib#CheckSyntaxGroups(atp_MathZones, line, col) && \ !atplib#CheckSyntaxGroups(['texMathText'], line, col) endif endfunction function! atplib#MakeMaps(maps, ...) let aucmd = ( a:0 >= 1 ? a:1 : '' ) for map in a:maps if map[3] != "" && ( !exists(map[5]) || {map[5]} > 0 || \ exists(map[5]) && {map[5]} == 0 && aucmd == 'InsertEnter' ) if exists(map[5]) && {map[5]} == 0 && aucmd == 'InsertEnter' exe "let ".map[5]." =1" endif exe map[0]." ".map[1]." ".map[2].map[3]." ".map[4] endif endfor endfunction function! atplib#DelMaps(maps) for map in a:maps let cmd = matchstr(map[0], '[^m]\ze\%(nore\)\=map') . "unmap" let arg = ( map[1] =~ '' ? '' : '' ) try exe cmd." ".arg." ".map[2].map[3] catch /E31:/ endtry endfor endfunction " From TeX_nine plugin: function! atplib#IsLeft(lchar,...) let nr = ( a:0 >= 1 ? a:1 : 0 ) let left = getline('.')[col('.')-2-nr] if left ==# a:lchar return 1 else return 0 endif endfunction " try function! atplib#ToggleIMaps(var, augroup, ...) if exists("s:isinmath") && \ ( atplib#IsInMath() == s:isinmath ) && \ ( a:0 >= 2 && a:2 ) && \ a:augroup == 'CursorMovedI' return endif call SetMathVimOptions() if atplib#IsInMath() call atplib#MakeMaps(a:var, a:augroup) else call atplib#DelMaps(a:var) if a:0 >= 1 && len(a:1) call atplib#MakeMaps(a:1) endif endif let s:isinmath = atplib#IsInMath() endfunction " catch E127 " endtry "}}} " Compilation Call Back Communication: " with some help of D. Munger " (Communications with compiler script: both in compiler.vim and the python script.) " {{{ Compilation Call Back Communication " TexReturnCode {{{ function! atplib#TexReturnCode(returncode) let b:atp_TexReturnCode=a:returncode endfunction "}}} " BibtexReturnCode {{{ function! atplib#BibtexReturnCode(returncode,...) let b:atp_BibtexReturnCode=a:returncode let b:atp_BibtexOutput= ( a:0 >= 1 ? a:1 : "" ) endfunction " }}} " MakeidxReturnCode {{{ function! atplib#MakeidxReturnCode(returncode,...) let b:atp_MakeidxReturnCode=a:returncode let b:atp_MakeidxOutput= ( a:0 >= 1 ? a:1 : "" ) endfunction " }}} " PlaceSigns {{{ function! atplib#Signs() if has("signs") sign unplace * " There is no way of getting list of defined signs in the current buffer. " Thus there is no proper way of deleting them. I overwrite them using " numbers as names. The vim help tells that there might be at most 120 " signs put. " But this is not undefineing signs. let qflist=getqflist() let g:qflist=qflist let i=1 for item in qflist if item['type'] == 'E' let hl = 'ErrorMsg' elseif item['type'] == 'W' let hl = 'WarningMsg' else let hl = 'Normal' endif exe 'sign define '.i.' text='.item['type'].': texthl='.hl exe 'sign place '.i.' line='.item['lnum'].' name='.i.' file='.expand('%:p') let i+=1 endfor endif endfunction "}}} " Callback {{{ " a:mode = a:verbose of s:compiler ( one of 'default', 'silent', " 'debug', 'verbose') " a:commnad = a:commmand of s:compiler " ( a:commnad = 'AU' if run from background) " " Uses b:atp_TexReturnCode which is equal to the value returned by tex " compiler. function! atplib#CallBack(mode,...) " If the compiler was called by autocommand. let AU = ( a:0 >= 1 ? a:1 : 'COM' ) " Was compiler called to make bibtex let BIBTEX = ( a:0 >= 2 ? a:2 : "False" ) let BIBTEX = ( BIBTEX == "True" || BIBTEX == 1 ? 1 : 0 ) let MAKEIDX = ( a:0 >= 3 ? a:3 : "False" ) let MAKEIDX = ( MAKEIDX == "TRUE" || MAKEIDX == 1 ? 1 : 0 ) if g:atp_debugCallBack exe "redir! > ".g:atp_TempDir."/CallBack.log" endif for cmd in keys(g:CompilerMsg_Dict) if b:atp_TexCompiler =~ '^\s*' . cmd . '\s*$' let Compiler = g:CompilerMsg_Dict[cmd] break else let Compiler = b:atp_TexCompiler endif endfor let b:atp_running = b:atp_running - 1 " Read the log file cgetfile " signs if g:atp_signs call atplib#Signs() endif if g:atp_debugCallBack silent echo "file=".expand("%:p") silent echo "g:atp_HighlightErrors=".g:atp_HighlightErrors endif if g:atp_HighlightErrors call atplib#HighlightErrors() endif " /this cgetfile is not working (?)/ let error = len(getqflist()) + (BIBTEX ? b:atp_BibtexReturnCode : 0) " If the log file is open re read it / it has 'autoread' opion set / checktime " redraw the status line /for the notification to appear as fast as " possible/ if a:mode != 'verbose' redrawstatus endif " redraw has values -0,1 " 1 do not redraw " 0 redraw " i.e. redraw at the end of function (this is done to not redraw twice in " this function) let l:clist = 0 let atp_DebugMode = t:atp_DebugMode if b:atp_TexReturnCode == 0 && ( a:mode == 'silent' || atp_DebugMode == 'silent' ) && g:atp_DebugMode_AU_change_cmdheight let &l:cmdheight=g:atp_cmdheight endif if g:atp_debugCallBack let g:debugCB = 0 let g:debugCB_mode = a:mode let g:debugCB_error = error silent echo "mode=".a:mode."\nerror=".error endif let msg_list = [] let showed_message = 0 if a:mode == "silent" && !error if t:atp_QuickFixOpen if g:atp_debugCallBack let g:debugCB .= 7 endif cclose call add(msg_list, ["[ATP:] no errors, closing quick fix window.", "Normal"]) endif elseif a:mode == "silent" && AU == "COM" if b:atp_TexReturnCode let showed_message = 1 call add(msg_list, ["[ATP:] ".Compiler." returned with exit code ".b:atp_TexReturnCode.".", 'ErrorMsg', 'after']) endif if BIBTEX && b:atp_BibtexReturnCode let showed_message = 1 call add(msg_list, ["[ATP:] ".b:atp_BibCompiler." returned with exit code ".b:atp_BibtexReturnCode.".", 'ErrorMsg', 'after']) endif if MAKEIDX && b:atp_Makeindex let showed_message = 1 call add(msg_list, ["[ATP:] makeidx returned with exit code ".b:atp_MakeidxReturnCode.".", 'ErrorMsg', 'after']) endif endif if a:mode ==? 'debug' && !error if g:atp_debugCallBack let g:debugCB .= 3 endif cclose call add(msg_list,["[ATP:] ".b:atp_TexCompiler." returned without errors [b:atp_ErrorFormat=".b:atp_ErrorFormat."]".(g:atp_DefaultDebugMode=='silent'&&atp_DebugMode!='silent'?"\ngoing out of debuging mode.": "."), "Normal", "after"]) let showed_message = 1 let t:atp_DebugMode = g:atp_DefaultDebugMode if g:atp_DefaultDebugMode == "silent" && t:atp_QuickFixOpen cclose endif let &l:cmdheight = g:atp_cmdheight endif " debug mode with errors if a:mode ==? 'debug' && error if len(getqflist()) if g:atp_debugCallBack let g:debugCB .= 4 endif let &l:cmdheight = g:atp_DebugModeCmdHeight let showed_message = 1 if b:atp_ReloadOnError || b:atp_Viewer !~ '^\s*xpdf\>' call add(msg_list, ["[ATP:] ".Compiler." returned with exit code " . b:atp_TexReturnCode . ".", (b:atp_TexReturnCode ? "ErrorMsg" : "Normal"), "before"]) else call add(msg_list, ["[ATP:] ".Compiler." returned with exit code " . b:atp_TexReturnCode . " output file not reloaded.", (b:atp_TexReturnCode ? "ErrorMsg" : "Normal"), "before"]) endif if !t:atp_QuickFixOpen let l:clist = 1 endif endif if BIBTEX && b:atp_BibtexReturnCode let l:clist = 1 call add(msg_list, [ "[Bib:] ".b:atp_BibtexCompiler." returned with exit code ".b:atp_BibtexReturnCode .".", "ErrorMsg", "after"]) call add(msg_list, [ "BIBTEX_OUTPUT" , "Normal", "after"]) endif if MAKEIDX && b:atp_MakeidxReturnCode let l:clist = 1 call add(msg_list, [ "[Bib:] makeidx returned with exit code ".b:atp_MakeidxReturnCode .".", "ErrorMsg", "after"]) call add(msg_list, [ "MAKEIDX_OUTPUT" , "Normal", "after"]) endif " In debug mode, go to first error. if a:mode ==# "Debug" if g:atp_debugCallBack let g:debugCB .= 6 endif cc endif endif if msg_list == [] if g:atp_debugCallBack redir END endif return endif " Count length of the message: let msg_len = len(msg_list) if len(filter(copy(msg_list), "v:val[0] == 'BIBTEX_OUTPUT'")) let msg_len += (BIBTEX ? len(split(b:atp_BibtexOutput, "\\n")) - 1 : - 1 ) endif if len(filter(copy(msg_list), "v:val[0] == 'MAKEIDX_OUTPUT'")) let msg_len += (MAKEIDX ? len(split(b:atp_MakeidxOutput, "\\n")) - 1 : - 1 ) endif " We never show qflist: (that's why it is commented out) " let msg_len += ((len(getqflist()) <= 7 && !t:atp_QuickFixOpen) ? len(getqflist()) : 0 ) " Show messages/clist if g:atp_debugCallBack let g:msg_list = msg_list let g:clist = l:clist silent echo "msg_list=\n**************\n".join(msg_list, "\n")."\n**************" silent echo "l:clist=".l:clist endif let cmdheight = &l:cmdheight if msg_len <= 2 let add=0 elseif msg_len <= 7 let add=1 else let add=2 endif let &l:cmdheight = max([cmdheight, msg_len+add]) let g:msg_len=msg_len if l:clist && len(getqflist()) > 7 && !t:atp_QuickFixOpen let winnr = winnr() copen exe winnr."wincmd w" elseif (a:mode ==? "debug") && !t:atp_QuickFixOpen let l:clist = 1 endif redraw let before_msg = filter(copy(msg_list), "v:val[2] == 'before'") let after_msg = filter(copy(msg_list), "v:val[2] == 'after'") for msg in before_msg exe "echohl " . msg[1] echo msg[0] endfor let l:redraw = 1 if l:clist && len(getqflist()) <= 7 && !t:atp_QuickFixOpen if g:atp_debugCallBack let g:debugCB .= "clist" endif try clist catch E42: endtry let l:redraw = 0 endif for msg in after_msg exe "echohl " . msg[1] if msg[0] !=# "BIBTEX_OUTPUT" echo msg[0] else echo " ".substitute(b:atp_BibtexOutput, "\n", "\n ", "g") " let bib_output=split(b:atp_BibtexOutput, "\n") " let len=max([10,len(bib_output)]) " below split +setl\ buftype=nofile\ noswapfile Bibtex\ Output " setl nospell " setl nonumber " setl norelativenumber " call append(0,bib_output) " resize 10 " redraw! " normal gg " nmap q :bd let g:debugCB .=" BIBTEX_output " endif endfor echohl Normal if len(msg_list)==0 redraw endif let &l:cmdheight = cmdheight if g:atp_debugCallBack redir END endif endfunction "}}} "{{{ LatexPID "Store LatexPIDs in a variable function! atplib#LatexPID(pid) call add(b:atp_LatexPIDs, a:pid) " call atplib#PIDsRunning("b:atp_BitexPIDs") let b:atp_LastLatexPID =a:pid endfunction "}}} "{{{ BibtexPID "Store BibtexPIDs in a variable function! atplib#BibtexPID(pid) call add(b:atp_BibtexPIDs, a:pid) " call atplib#PIDsRunning("b:atp_BibtexPIDs") endfunction "}}} "{{{ MakeindexPID "Store MakeindexPIDs in a variable function! atplib#MakeindexPID(pid) call add(b:atp_MakeindexPIDs, a:pid) let b:atp_LastMakeindexPID =a:pid endfunction "}}} "{{{ PythonPID "Store PythonPIDs in a variable function! atplib#PythonPID(pid) call add(b:atp_PythonPIDs, a:pid) " call atplib#PIDsRunning("b:atp_PythonPIDs") endfunction "}}} "{{{ MakeindexPID "Store MakeindexPIDs in a variable function! atplib#PythonPIDs(pid) call add(b:atp_PythonPIDs, a:pid) let b:atp_LastPythonPID =a:pid endfunction "}}} "{{{ PIDsRunning function! atplib#PIDsRunning(var) " a:var is a string, and might be one of 'b:atp_LatexPIDs', 'b:atp_BibtexPIDs' or " 'b:atp_MakeindexPIDs' python << EOL import psutil, re, sys, vim var = vim.eval("a:var") pids = vim.eval(var) if len(pids) > 0: ps_list=psutil.get_pid_list() rmpids=[] for lp in pids: run=False for p in ps_list: if str(lp) == str(p): run=True break if not run: rmpids.append(lp) rmpids.sort() rmpids.reverse() for pid in rmpids: vim.eval("filter("+var+", 'v:val !~ \""+str(pid)+"\"')") EOL endfunction "}}} "{{{ ProgressBar function! atplib#ProgressBar(value,pid) if a:value != 'end' let b:atp_ProgressBar[a:pid]=a:value else call remove(b:atp_ProgressBar, a:pid) endif redrawstatus endfunction "}}} "{{{ redrawstatus function! atplib#redrawstatus() redrawstatus endfunction "}}} "{{{ CursorMoveI " function! atplib#CursorMoveI() " if mode() != "i" " return " endif " let cursor_pos=[ line("."), col(".")] " call feedkeys("\", "n") " call cursor(cursor_pos) " endfunction "}}} " {{{ HighlightErrors function! atplib#HighlightErrors() call atplib#ClearHighlightErrors() let qf_list = getqflist() for error in qf_list if error.type ==? 'e' let hlgroup = g:atp_Highlight_ErrorGroup else let hlgroup = g:atp_Highlight_WarningGroup endif if hlgroup == "" continue endif let m_id = matchadd(hlgroup, '\%'.error.lnum.'l.*', 20) call add(s:matchid, m_id) let error_msg=split(error.text, "\n") endfor endfunction "}}} " {{{ ClearHighlightErrors function! atplib#ClearHighlightErrors() if !exists("s:matchid") let s:matchid=[] return endif for m_id in s:matchid try silent call matchdelete(m_id) catch /E803:/ endtry endfor let s:matchid=[] endfunction "}}} "{{{ echo function! atplib#Echo(msg, cmd, hlgroup, ...) if a:0 >= 1 && a:1 redraw endif exe "echohl ".a:hlgroup exe a:cmd." '".a:msg."'" echohl Normal endfunction "}}} " }}} " Toggle On/Off Completion " {{{1 atplib#OnOffComp function! atplib#OnOffComp(ArgLead, CmdLine, CursorPos) return filter(['on', 'off'], 'v:val =~ "^" . a:ArgLead') endfunction "}}}1 " Open Function: "{{{1 atplib#Open " a:1 - pattern or a file name " a:1 is regarded as a filename if filereadable(pattern) is non " zero. function! atplib#Open(bang, dir, TypeDict, ...) if a:dir == "0" echohl WarningMsg echomsg "You have to set g:atp_LibraryPath in your vimrc or atprc file." echohl Normal return endif let pattern = ( a:0 >= 1 ? a:1 : "") let file = filereadable(pattern) ? pattern : "" if file == "" if a:bang == "!" || !exists("g:atp_Library") let g:atp_Library = filter(split(globpath(a:dir, "*"), "\n"), 'count(keys(a:TypeDict), fnamemodify(v:val, ":e"))') let found = deepcopy(g:atp_Library) else let found = deepcopy(g:atp_Library) endif call filter(found, "fnamemodify(v:val, ':t') =~ pattern") " Resolve symlinks: call map(found, "resolve(v:val)") " Remove double entries: call filter(found, "count(found, v:val) == 1") if len(found) > 1 echohl Title echo "Found files:" echohl Normal let i = 1 for file in found if len(map(copy(found), "v:val =~ escape(fnamemodify(file, ':t'), '~') . '$'")) == 1 echo i . ") " . fnamemodify(file, ":t") else echo i . ") " . pathshorten(fnamemodify(file, ":p")) endif let i+=1 endfor let choice = input("Which file to open? ")-1 if choice == -1 return endif let file = found[choice] elseif len(found) == 1 let file = found[0] else echohl WarningMsg echomsg "[ATP:] Nothing found." echohl None return endif endif let ext = fnamemodify(file, ":e") let viewer = get(a:TypeDict, ext, 0) if viewer == '0' echomsg "\n" echomsg "[ATP:] filetype: " . ext . " is not supported, add an entry to g:atp_OpenTypeDict" return endif if viewer !~ '^\s*cat\s*$' && viewer !~ '^\s*g\=vim\s*$' && viewer !~ '^\s*edit\s*$' && viewer !~ '^\s*tabe\s*$' && viewer !~ '^\s*split\s*$' call system(viewer . " '" . file . "' &") elseif viewer =~ '^\s*g\=vim\s*$' || viewer =~ '^\s*tabe\s*$' exe "tabe " . fnameescape(file) setl nospell elseif viewer =~ '^\s*edit\s*$' || viewer =~ '^\s*split\s*$' exe viewer . " " . fnameescape(file) setl nospell elseif viewer == '^\s*cat\s*' redraw! echohl Title echo "cat '" . file . "'" echohl Normal echo system(viewer . " '" . file . "' &") endif " if fnamemodify(file, ":t") != "" && count(g:atp_open_completion, fnamemodify(file, ":t")) == 0 " call extend(g:atp_open_completion, [fnamemodify(file, ":t")], 0) " endif " This removes the hit Enter vim prompt. call feedkeys("") return endfunction "}}}1 " Find Vim Server: find server 'hosting' a file and move to the line. " {{{1 atplib#FindAndOpen " Can be used to sync gvim with okular. " just set in okular: " settings>okular settings>Editor " Editor Custom Text Editor " Command gvim --servername GVIM --remote-expr "atplib#FindAndOpen('%f','%l', '%c')" " You can also use this with vim but you should start vim with " vim --servername VIM " and use servername VIM in the Command above. function! atplib#ServerListOfFiles() exe "redir! > " . g:atp_TempDir."/ServerListOfFiles.log" let file_list = [] for nr in range(1, bufnr('$')-1) " map fnamemodify(v:val, ":p") is not working if we are in another " window with file in another dir. So we are not using this (it might " happen that we end up in a wrong server though). let files = getbufvar(nr, "ListOfFiles") let main_file = getbufvar(nr, "atp_MainFile") if string(files) != "" call add(file_list, main_file) endif if string(main_file) != "" call extend(file_list, files) endif endfor call filter(file_list, 'v:val != ""') redir end return file_list endfunction function! atplib#FindAndOpen(file, line, ...) let col = ( a:0 >= 1 && a:1 > 0 ? a:1 : 1 ) let file = ( fnamemodify(a:file, ":e") == "tex" ? a:file : fnamemodify(a:file, ":p:r") . ".tex" ) let g:file = file let file_t = fnamemodify(file, ":t") let g:file_t = file_t let server_list = split(serverlist(), "\n") " exe "redir! >".g:atp_TempDir."/FindAndOpen.log" exe "redir! > /tmp/FindAndOpen.log" if len(server_list) == 0 return 1 endif let use_server = "" let use_servers = [] for server in server_list let file_list=split(remote_expr(server, 'atplib#ServerListOfFiles()'), "\n") let cond_1 = (index(file_list, file) != "-1") let cond_2 = (index(file_list, file_t) != "-1") if cond_1 let use_server = server break elseif cond_2 call add(use_servers, server) endif endfor " If we could not find file name with full path in server list use the " first server where is fnamemodify(file, ":t"). if use_server == "" let use_server=get(use_servers, 0, "") endif let g:use_server=use_server if use_server != "" call system(v:progname." --servername ".use_server." --remote-wait +".a:line." ".fnameescape(file) . " &") Test this for file names with spaces let bufwinnr = remote_expr(use_server, 'bufwinnr("'.file.'")') let g:use_server=use_server let g:bufwinnr = bufwinnr if bufwinnr == "-1" " " The buffer is in a different tab page. let tabpage = 1 " " Find the correct tabpage: for tabnr in range(1, remote_expr(use_server, 'tabpagenr("$")')) let tabbuflist = split(remote_expr(use_server, 'tabpagebuflist("'.tabnr.'")'), "\n") let tabbuflist_names = split(remote_expr(use_server, 'map(tabpagebuflist("'.tabnr.'"), "bufname(v:val)")'), "\n") if count(tabbuflist_names, file) || count(tabfublist_names, file_t) let tabpage = tabnr break endif endfor " Goto to the tabpage: if remote_expr(use_server, 'tabpagenr()') != tabpage call remote_send(use_server, ':tabnext '.tabpage.'') endif " Check the bufwinnr once again: let bufwinnr = remote_expr(use_server, 'bufwinnr("'.file.'")') endif let g:bufwinnr= bufwinnr " winnr() doesn't work remotely, this is a substitute: let remote_file = remote_expr(use_server, 'expand("%:t")') let g:remote_file = remote_file if remote_file != file_t call remote_send(use_server, ":".bufwinnr."wincmd w") else call remote_expr(use_server, 'cursor('.a:line.','.col.')') call remote_send(use_server, ':redraw') endif return use_server endfunction "}}}1 " Labels Tools: GrepAuxFile, SrotLabels, generatelabels and showlabes. " {{{1 LABELS " the argument should be: resolved full path to the file: " resove(fnamemodify(bufname("%"),":p")) " {{{2 --------------- atplib#GrepAuxFile " This function searches in aux file (actually it tries first ._aux file, " made by compile.py - this is because compile.py is copying aux file only if " there are no errors (for to not affect :Labels command) function! atplib#GrepAuxFile(...) " Aux file to read: if exists("b:atp_MainFile") let atp_MainFile = atplib#FullPath(b:atp_MainFile) endif if filereadable(fnamemodify(atp_MainFile, ":r") . "._aux") let aux_filename = ( a:0 == 0 && exists("b:atp_MainFile") ? fnamemodify(atp_MainFile, ":r") . "._aux" : a:1 ) else let aux_filename = ( a:0 == 0 && exists("b:atp_MainFile") ? fnamemodify(atp_MainFile, ":r") . ".aux" : a:1 ) endif let tex_filename = fnamemodify(aux_filename, ":r") . ".tex" if !filereadable(aux_filename) " We should worn the user that there is no aux file " /this is not visible ! only after using the command 'mes'/ echohl WarningMsg echomsg "[ATP:] there is no aux file. Run ".b:atp_TexCompiler." first." echohl Normal return [] " CALL BACK is not working " I can not get output of: vim --servername v:servername --remote-expr v:servername " for v:servername " Here we should run latex to produce auxfile " echomsg "Running " . b:atp_TexCompiler . " to get aux file." " let labels = system(b:atp_TexCompiler . " -interaction nonstopmode " . atp_MainFile . " 1&>/dev/null 2>1 ; " . " vim --servername ".v:servername." --remote-expr 'atplib#GrepAuxFile()'") " return labels endif " let aux_file = readfile(aux_filename) let saved_llist = getloclist(0) if bufloaded(aux_filename) exe "silent! bd! " . bufnr(aux_filename) endif try silent execute 'lvimgrep /\\newlabel\s*{/j ' . fnameescape(aux_filename) catch /E480:/ endtry let loc_list = getloclist(0) call setloclist(0, saved_llist) call map(loc_list, ' v:val["text"]') let labels = [] if g:atp_debugGAF let g:gaf_debug = {} endif " Equation counter depedns on the option \numberwithin{equation}{section} " /now this only supports article class. let equation = len(atplib#GrepPreambule('^\s*\\numberwithin{\s*equation\s*}{\s*section\s*}', tex_filename)) " for line in aux_file for line in loc_list if line =~ '\\newlabel\>' " line is of the form: " \newlabel{