Note that there are some explanatory texts on larger screens.

plurals
  1. POVim script to compile TeX source and launch PDF only if no errors
    primarykey
    data
    text
    <p>I am switching to using Vim for for my LaTeX editing environment. I would like to be able to tex the source file from within Vim, and launch an external viewing if the compile was successful.</p> <p>I know about the Vim-Latex suite, but, if possible, would prefer to avoid using it: it is pretty heavy-weight, hijacks a <em>lot</em> of my keys, and clutters up my vimruntime with a lot of files. </p> <p>Here is what I have now:</p> <pre><code>if exists('b:tex_build_mapped') finish endif " use maparg or mapcheck to see if key is free command! -buffer -nargs=* BuildTex call BuildTex(0, &lt;f-args&gt;) command! -buffer -nargs=* BuildAndViewTex call BuildTex(1, &lt;f-args&gt;) noremap &lt;buffer&gt; &lt;silent&gt; &lt;F9&gt; &lt;Esc&gt;:call BuildTex(0)&lt;CR&gt; noremap &lt;buffer&gt; &lt;silent&gt; &lt;S-F9&gt; &lt;Esc&gt;:call BuildTex(1)&lt;CR&gt; let b:tex_build_mapped = 1 if exists('g:tex_build_loaded') finish endif let g:tex_build_loaded = 1 function! BuildTex(view_results, ...) write if filereadable("Makefile") " If Makefile is available in current working directory, run 'make' with arguments echo "(using Makefile)" let l:cmd = "!make ".join(a:000, ' ') echo l:cmd execute l:cmd if a:view_results &amp;&amp; v:shell_error == 0 call ViewTexResults() endif else let b:tex_flavor = 'pdflatex' compiler tex make % if a:view_results &amp;&amp; v:shell_error == 0 call ViewTexResults() endif endif endfunction function! ViewTexResults(...) if a:0 == 0 let l:target = expand("%:p:r") . ".pdf" else let l:target = a:1 endif if has('mac') execute "! open -a Preview ".l:target endif endfunction </code></pre> <p>The problem is that <code>v:shell_error</code> is not set, even if there are compile errors. Any suggestions or insight on how to detect whether a compile was successful or not would be greatly appreciated! Thanks!</p> <hr> <p>Between the answers given here, plus some study of other approaches, I think that this has been satisfactorily solved. I am posting the solution here in case anyone else is interested.</p> <p>Basically, the best solution appears to be to use <a href="http://www.pps.jussieu.fr/~beffara/soft/rubber/" rel="noreferrer">Rubber</a>, a wrapper around LaTeX, that generally "just works", and provides very clean output/errors. The solution I present below preferentially uses Rubber if it is found on the system and no Makefile is found in the current directory. If a Makefile is found, it uses that instead. If there is no Makefile and Rubber is not installed, it uses pdflatex. In all cases, if the source fails to compile, the (filtered and parsed) errors are sent to the QuickFix buffer and the QuickFix window is automatically opened. If it compiles successfully, a short message is written, and if the user requested it, the PDF will be opened for viewing. </p> <p>In my own installation, I have lifted the (<em>excellent</em>) "SetLatexEfm()" function from <a href="http://vim-latex.sourceforge.net/" rel="noreferrer">Vim-Latex</a> to parse and filter the tex build output. If this function is not found, however, the function below defaults to setting an error message format that works fine enough for the errors to be identified and highlighted in the QuickFix window, albeit with lots of crud.</p> <pre><code> function! BuildTex(view_results, ...) " record position let save_cursor = getpos(".") " save work silent write " From: http://stackoverflow.com/questions/2679475/vim-script-to-compile-tex-source-and-launch-pdf-only-if-no-errors " If your shell is bash, you can use the ${PIPESTATUS} array variable to get " the correct exit code (borrowed from this answer to another question). silent setlocal shell=bash silent setlocal shellpipe=2&gt;&amp;1\ \|\ tee\ %s;exit\ \${PIPESTATUS[0]} let success = 1 if filereadable("Makefile") " If Makefile is available in current working directory, run 'make' with arguments echon "compiling using Makefile ..." let l:makecmd = "make\\ ".join(a:000, '\\ ') silent execute "setlocal makeprg=" . l:makecmd try " This function is defined in the Vim-Latex package, " and provides excellent parsing and filtering of the error messages " when running latex outside of the Rubber wrapper. call s:SetLatexEfm() catch /E117/ set errorformat=%E!\ LaTeX\ %trror:\ %m, \%E!\ %m, \%+WLaTeX\ %.%#Warning:\ %.%#line\ %l%.%#, \%+W%.%#\ at\ lines\ %l--%*\\d, \%WLaTeX\ %.%#Warning:\ %m, \%Cl.%l\ %m, \%+C\ \ %m., \%+C%.%#-%.%#, \%+C%.%#[]%.%#, \%+C[]%.%#, \%+C%.%#%[{}\\]%.%#, \%+C&lt;%.%#&gt;%.%#, \%C\ \ %m, \%-GSee\ the\ LaTeX%m, \%-GType\ \ H\ &lt;return&gt;%m, \%-G\ ...%.%#, \%-G%.%#\ (C)\ %.%#, \%-G(see\ the\ transcript%.%#), \%-G\\s%#, \%+O(%f)%r, \%+P(%f%r, \%+P\ %\\=(%f%r, \%+P%*[^()](%f%r, \%+P[%\\d%[^()]%#(%f%r, \%+Q)%r, \%+Q%*[^()])%r, \%+Q[%\\d%*[^()])%r endtry silent make else let l:special_tex_compiler = "rubber" if executable(l:special_tex_compiler) echon "compiling with Rubber ..." silent execute "setlocal makeprg=" . l:special_tex_compiler . "\\ -dfs\\ %" setlocal errorformat=%f:%l:\ %m silent make % else echon "compiling ..." let b:tex_flavor = 'pdflatex' compiler tex silent make % endif endif " set/report compile status if v:shell_error let l:success = 0 " let l:wheight = winheight(bufnr("%")) / 2 " execute "copen ".l:wheight copen else let l:success = 1 cclose redraw echon "successfully compiled" endif " view results if successful compile if l:success &amp;&amp; a:view_results call ViewTexResults() endif " restore position call setpos('.', save_cursor) endfunction function! ViewTexResults(...) if a:0 == 0 let l:target = expand("%:p:r") . ".pdf" else let l:target = a:1 endif if has('mac') silent execute "! open -a Preview ".l:target " obviously, you will need to write specific commands for other systems " left as an exercise for the reader ... endif endfunction command! -buffer -nargs=* BuildTex call BuildTex(0, &lt;f-args&gt;) command! -buffer -nargs=* BuildAndViewTex call BuildTex(1, &lt;f-args&gt;) noremap &lt;buffer&gt; &lt;silent&gt; &lt;F9&gt; &lt;Esc&gt;:call BuildTex(0)&lt;CR&gt; noremap &lt;buffer&gt; &lt;silent&gt; &lt;S-F9&gt; &lt;Esc&gt;:call BuildTex(1)&lt;CR&gt; </code></pre> <hr> <p>Update: I have packaged and published this as a Vim file-type plugin script, available at: <a href="http://www.vim.org/scripts/script.php?script_id=3230" rel="noreferrer">http://www.vim.org/scripts/script.php?script_id=3230</a>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload