Vim for LaTeX, part 3

UPDATE: I added a solu­tion to my gripe about LaTeX-suite’s use of the back tick below.

This is part three of my multi-part series on set­ting up Vim as a writ­ing envi­ron­ment for LaTeX. Last week I wrote a cou­ple of posts about my basic Vim setup in my .vimrc. Today I’ll explain the setup and basic usage of my favorite LaTeX plugin.

If you are writ­ing papers in LaTeX using Vim, you’ll want to get a plu­gin to help. You are going to want to com­pile your doc­u­ment from within Vim (for a long time I opened TeXShop just to com­pile my papers; it wasn’t effi­cient). And you’ll want to be able to set up cita­tion com­ple­tion. Plus, there are a num­ber of key bind­ings and short­cuts that can make your LaTeX com­po­si­tion easier.

The plu­gin

There are a num­ber of LaTeX plu­g­ins you can choose from. The most pop­u­lar is prob­a­bly the LaTeX-suite. That is a very com­plete plugin—it includes every­thing, even a num­ber of the pack­age files you might use in your doc­u­ment. I used to use this plu­gin, but after look­ing around at other options, I decided to bail on it.

There were three rea­sons that lead me to look for other options. First, I real­ized that cus­tomiz­ing the plu­gin (to get the cita­tion com­ple­tion to work, to get my papers to com­pile cor­rectly) was entirely too much work. Sec­ond, it looks like the plu­gin is no longer sup­ported by a developer—the files were updated the last time in 2004. That makes me slightly uncom­fort­able. Third, some of the key bind­ings drove me crazy. With the LaTeX-suite plu­gin, the back tick is involved in a num­ber of key bind­ings. So type `p and it is replaced with \pi. The idea is to make it eas­ier to type Greek let­ters if you can’t remem­ber the sym­bols. But the actual effect for me is that any time I needed to write a sin­gle quote (which is fairly often), I would need to write the let­ter, then arrow back­ward, then type the back tick, then arrow for­ward. I could prob­a­bly track down the lines/files to delete in order to elim­i­nate this behav­ior. But this was not the main issue, just one among many.

UPDATE: Shane Steinert-Threlkeld has pointed out to me that one can avoid this final worry I have with the LaTeX-suite plu­gin. He writes about chang­ing the LaTeX-suite leader over on his blog. Here is the short and sweet ver­sion: put let g:Tex_Leader=',' some­where in your .vimrc file. This will change the leader (for LaTeX-suite spe­cific com­mands, not for all Vim com­mands) from the back tick to the comma. You could use any­thing you like if you use the comma for some­thing else. So instead of `b insert­ing \beta, you could insert that with ,b.

After look­ing around, I decided to try out, and then really liked, the LaTeX-box plu­gin. This is a much more min­i­mal plu­gin, but I think it works much bet­ter (at least for me). The plu­gin offers all the things I need: it lets me com­pile my papers and it gives me cita­tion com­ple­tion abil­i­ties. And it includes some bonus fea­tures I didn’t expect but quite like (e.g., a key map­ping to close the last opened envi­ron­ment, and one to gen­er­ate a table of con­tents for nav­i­ga­tion purposes).

After using the plu­gin for a cou­ple of weeks (and inter­act­ing with the devel­oper, who is really great, by email), I decided to stick with the LaTeX-box plu­gin and not try some of the other options like auctex.vim and the Auto­matic TeX­Plu­gin. If you are look­ing for a Vim LaTeX plu­gin, give this one a shot.

The devel­oper chose to use the Vim­ball for­mat for pack­ag­ing the LaTeX-box plu­gin, which means try­ing it out couldn’t be eas­ier. (You’ll want to remove any other LaTeX plu­g­ins you have installed. If you have the LaTeX-suite installed, this is a lot of files. I down­loaded that plu­gin just so I could see all the files to delete. This was mod­er­ately tedious, but worth it.)

Steps to install the plugin:

  1. Down­load it first: you can get the plu­gin at http://​www​.vim​.org/​s​c​r​i​p​t​s​/​s​c​r​i​p​t​.​p​h​p​?​s​c​r​i​p​t​_​i​d​=​3​109.
  2. Open the LatexBox.vba file with Vim, MacVim, or gVim.
  3. Once you open the file, in nor­mal mode type :so %. This tells Vim to source the cur­rent file.

That’s it. The Vim­ball for­mat means you can unin­stall the plu­gin by sim­ply open­ing Vim (any file will do here) and typ­ing :RmVimball latex-box (I think that is right, but it might be ‘Latex-box’ or ‘LaTeX-box’). If you try installing the LaTeX-suite at any point (and espe­cially if you try to unin­stall it), you’ll come to appre­ci­ate Vim­balls pretty quickly.

Basic plu­gin functionality

Latex-box does two things quite well: LaTeX com­pi­la­tion and cita­tion com­ple­tion. It has some other fea­tures, but those are the two main things this fairly min­i­mal plu­gin was designed to do.

Latex-box com­piles your paper with latexmk. To com­pile your paper, when you are in nor­mal mode hit <leader>ll. The default <leader> is the back­slash. So to com­pile you’ll hit \ll. Once you start latexmk, it will run until you quit Vim. That means any changes you make to the file (i.e., any changes you save) will auto­mat­i­cally be com­piled. What’s more, latexmk is setup to com­pile as many times as nec­es­sary to resolve all issues. If you have sec­tion ref­er­ences and a bib­li­og­ra­phy, if you com­pile by hand you have to run latex, run bib­tex, then run latex at least twice more. Latex-box (thanks to latexmk) will take care of all of that for you. One \ll will pro­duce a com­plete paper.

There are a hand­ful of other com­pi­la­tion com­mands you might want to use with latex-box. Typ­ing \lv should open the viewer you want (more on that in the next sec­tion). If you want to stop latexmk, type \lk. If you want to clean out the cruft files that com­pi­la­tion cre­ates, hit \lc. If you want to clean out all the files besides your .tex file (pdf file included), hit \lC.

One fea­ture I really like is the table of con­tents com­mand (you’ll need to have com­piled your paper and not got­ten rid of the .toc file for this one to work): hit \lt and you will get a ver­ti­cal split win­dow over on the left of your main Vim win­dow. It will list all the sec­tions of your paper. Nav­i­gate to the one you want and hit Enter and the split will dis­ap­pear and you’ll go to that sec­tion in your .tex file. (In this split win­dow you can use all the basic Vim commands—so if sec­tion 7 is on line 10, type 10G and you’ll go directly to that line of the window.)

Latex-box uses the Omni Com­plete func­tion to do cita­tion and ref­er­ence com­ple­tion. So if you type \cite{ then hit Control+x then Control+o, you’ll get a nice lit­tle pop up win­dow with all your pos­si­ble cita­tions in it. Scroll down to the one you want using the arrow keys. (You may have to hit Enter, some­times I seem to, other times I just hit the space bar or close the }.) If you type the first few let­ters of your cite key the com­ple­tion list will be more man­age­able. You can also do ref­er­ence com­ple­tion: hit the Omni Com­plete keys in a \ref{sec: envi­ron­ment and you’ll get a list of all your sec­tions (if you gave them labels via a \label{sec:section_name} com­mand, of course).

.vimrc set­tings

There are a cou­ple of options you can set with the Latex-box plu­gin. Two that I set gov­ern the behav­ior of Latexmk, which Latex-box uses to com­pile your tex file. I use Skim as my pdf viewer on the Mac (for these pur­poses at least). I pri­mar­ily like Skim for use with Latex-box because it can auto-update and it works with Sync­TeX. If you run latexmk with the right options, then when­ever you make changes to your file and save them, latexmk recom­piles your doc­u­ment. If you con­fig­ure your pdf viewer right, you can see the changes right away. (You can find out more about latexmk’s options by look­ing at this doc­u­men­ta­tion).

So I put the fol­low­ing in my ~/.vimrc file:

let g:LatexBox_viewer = 'skim'
let g:LatexBox_latexmk_options = '-pvc'

The -pvc option tells latexmk to open my pdf viewer (that is the ‘pv’ part) and then mon­i­tor it con­tin­u­ously. Leave off the ‘c’ if you don’t want it to auto-update.

To use the auto-updating, you need a pdf viewer that will watch a pdf file for changes. If you are using Skim, go to Skim -> Preferences -> Sync and select ‘Check file for changes’. Now when you save a change to your tex file, if latexmk is run­ning, the change will be made auto­mat­i­cally to the pdf (this is espe­cially nice if you are using Sync­TeX, so you can quickly go to that sec­tion of the pdf with­out track­ing it down manually.

Latex-box offers nice cita­tion com­ple­tion capa­bil­i­ties. It already knows where your bib file is (if it is in one of the stan­dard loca­tions), so you don’t have to spec­ify that the way you do with the LaTeX-suite plu­gin. To use cita­tion (or \ref com­ple­tion), you need to use the Omni Com­plete func­tion of Vim. To do that, you hit Control+X Control+O.

I make two changes to my ~/.vimrc to make cita­tion com­ple­tion run more smoothly. First, I remap the F9 key to do the Omni Com­plete stuff. I use com­ple­tion enough to make that well worth my while (why hit two com­pli­cated keys when I can hit one?). The other change is to the cite pat­tern. By default, Latex-box only knows that a few cita­tion com­mands are cita­tion com­mands. So if you only use \cite, \citet, and \citep you are fine. But if you ever use natbib’s \citeyearpar or \citealt, you won’t be able to use cita­tion com­ple­tion. And if you use prac­ti­cally any of the BibLa­TeX cita­tion com­mands (e.g., \Cite) you won’t be able to use cita­tion com­ple­tion. A slight change will make all these work, how­ever. Just add the sec­ond line below to your ~/.vimrc to make this work.

inoremap  
let g:LatexBox_cite_pattern = '\c\\\a*cite\a*\*\?\_\s*{'

Set­tings in a .vim/ftplugin/tex.vim file

There are some key map­pings that I want to use, but that I don’t need to be avail­able for every doc­u­ment I write. I use Omni Com­ple­tion for other kinds of files, so I put that map­ping in my ~/.vimrc. But I won’t use com­mands to close a LaTeX envi­ron­ment in any other kind of file.

So I cre­ated a file at ~/.vim/ftplugin/tex.vim. This file takes set­tings just like your ~/.vimrc file does, but it only applies them to .tex files. The fol­low­ing (save the first one) all come directly from the doc­u­men­ta­tion for this plu­gin; the first is just my pref­er­ence. I’ll explain them all after I list them.

setlocal formatoptions+=wa
imap  [[ \begin{
imap  ]] LatexCloseLastEnv
nmap   LatexChangeEnv
vmap   LatexWrapSelection
vmap   LatexWrapSelectionEnv
map  ls :silent !/Applications/Skim.app/Contents/SharedSupport/displayline 
  \ =line('.') "=LatexBox_GetOutputFile()" "%:p" 

Else­where I set my lines to hard wrap at 72 char­ac­ters (at the clos­est word). In what fol­lows, the ‘a’ option tells Vim to fill that in automatically—if I delete a word from line 3 it moves a word up from line 4. The ‘w’ option tells Vim that a line that ends in a space indi­cates that the para­graph con­tin­ues; a line that ends in any­thing other than a space indi­cates the end of the para­graph. You can get away with hard wrap­ping in LaTeX because LaTeX only counts a new para­graph if it encoun­ters a \ or a blank line. In nor­mal mode, type :h fo-table for more on these options.

The rest make using envi­ron­ments eas­ier: [[ will insert a \begin{ and ]] will insert \end{env} for what­ever envi­ron­ment was opened most recently. If you put your cur­sor (in nor­mal mode) on the envi­ron­ment name in a \begin{} or \end{}, F5 will ask you what you want to change it to, then change it. If you switch to Visual mode, you can use the next two com­mands. (Switch to visual mode by hit­ting ‘v’ in nor­mal mode. This is kind of like hold­ing down your mouse but­ton and select­ing a swath of text.) In visual mode, if you select a word or series of words and hit F7, they will be wrapped in curly braces and a back­slash and your cur­sor will be put in front (so this would be trans­formed to \^{this}, where the caret rep­re­sents your cur­sor). Do the same and hit Shift+F7 and the selec­tion will be wrapped in \begin{} \end{} tags.

The last one is very nice. If you use Skim (which sup­ports Sync­TeX for sync­ing your .tex and .pdf files), then if you include this line, while latexmk is run­ning a \ls will take you from your tex file to that line in your pdf file (if Skim is open, of course). Note that this isn’t as sen­si­tive as the TeXShop ver­sion: if you use soft wrapped lines (one line per para­graph, say), then this will take you to the start of the para­graph. But if you hard wrap your lines and keep them shorter (like 72 or 80 char­ac­ters), this will take you right to the word under the cur­sor. I don’t know how to gen­er­al­ize this if you use Ubuntu or some­thing, or even if you use another viewer on your Mac. But this works for Skim.

XƎTeX

If you like to use XƎTeX, Latex-box and latexmk can accom­mo­date that. Just how you set it up depends on how often you use XƎTeX v. LaTeX. In short, you need to cre­ate a file to tell latexmk that you are using XƎTeX. If you use XƎTeX for all your LaTeX needs, then you can cre­ate this file in your home direc­tory. Just call it .latexmkrc. If you only want to use XƎTeX for some of your projects, don’t cre­ate that file; instead, cre­ate a file in the direc­tory of your XƎTeX project called either latexmkrc or .latexmkrc. Either name is fine.

Regard­less of where you put that file, it will have the same con­tents: a sin­gle line that says

$pdflatex = 'xelatex %O %S'

[UPDATE: Be sure to check out Kevin’s clever script below. If you run this, it will deter­mine whether you plan to use xela­tex or not and will avoid the need for you to cre­ate a latexmkrc file on a per-project basis. Very handy.]

Sync­TeX

If you want to use Sync­TeX you need to do two things. First, you need to insert a line in the pro­logue of your paper:

\synctex=1

Sec­ond, you need to set up a pdf viewer that has Sync­TeX capa­bil­i­ties. I’m not the man to ask about view­ers other than Skim (and I don’t even have too many answers about it). If you’ve spec­i­fied an appro­pri­ate viewer in your .vimrc (above), and if you’ve put the appro­pri­ate key map­ping in your ~/.vim/ftplugin/tex.vim file, then an \ls ought to take you to the line under the cursor.

You can also set up Sync­TeX and Skim to go the other way around—from the pdf to the tex file, but I’m not entirely sure how that works. I’m hop­ing to look into it in the com­ing weeks, and if I fig­ure it out I’ll write about it.

Until then, I can’t rec­om­mend the Latex-box plu­gin enough. I think it is an effi­cient LaTeX plu­gin for Vim that does all the things I need it to. If your needs are like mine, I think you’ll prob­a­bly like it quite a bit.

Posted Tuesday, August 3rd, 2010 under LaTeX, text editors.

16 comments

  1. Regard­ing the back­tick issue, a lot of LaTeX edi­tors (Kile, Tex­maker, Tex­works, LyX, Emacs with AUC­TeX, TeXnic­Cen­ter if mem­ory serves, prob­a­bly some oth­ers) have (the equiv­a­lent of) a “smart quote” fea­ture, which, depend­ing on con­text, autom­i­cally change a dou­ble quote to either two back­ticks or two apos­tro­phes (or even the Uni­code “ and ”) depend­ing on con­text, and sim­i­larly will change an apos­tro­phe to a back­tick at the begin­ning of a word. That would free up using an explicit back­tick for other pur­poses. Do you know of any way of get­ting that with Vim? (I think I might be able to do it with autokey, but I’d pre­fer to do it from within vim itself.)

    As for Sync­TeX forward/reverse search, this sup­ported by Oku­lar on linux (and will be sup­ported by the next ver­sion of evince). Suma­traPDF sup­ports this on Win­dows. I had forward/reverse work­ing in both direc­tions between Oku­lar and the vim LaTeX suite (e.g., \ls in gvim to find the match­ing spot in Oku­lar), shift click in Oku­lar to jump to the match­ing spot in the source. If I can remem­ber how, I can post instruc­tions if any­one is inter­ested. Should be pos­si­ble to get it work­ing in the other direc­tion with skim, but don’t ask me how.

    It should also be pos­si­ble to con­fig­ure things so that latexmk always calls –synctex=1 when com­pil­ing so you don’t need \synctex=1 in your source file.

  2. Here’s a trick you to make it easy to tell LaTeX­make to use xela­tex or pdfla­tex. I wrote a shell script that will read the first 5 lines of an input file and then either call xela­tex or pdfla­tex (I called it xepdfla​tex​.sh) depend­ing on whether or not it includes the phrase ‘xela­tex’ in its first five lines. It looks like this:

    #!/bin/bash
    file="$1"
    if head -n 5 "$file" | grep -i -q 'xelatex' ; then
        xelatex --interaction=nonstopmode --synctex=1 "$file"
    else
        pdflatex --interaction=nonstopmode --synctex=1 "$file"
    fi 
    

    And then in my pri­mary .latexmkrc in my home directory:

    $pdflatex = 'xepdflatex.sh %S';
    $pdf_mode = 1;
    $pdf_previewer = 'zathura %O %S';
    $pdf_update_method = 0;
    

    (The impor­tant thing here is the first line, which tells it to use the script as its form of pdflatex.)

    Then instead of mak­ing sep­a­rate latexmkrc files for each project, I just stick a com­ment line:

    % xelatex
    

    at the begin­ning of any file that needs to be processed with xelatex.

    (A tweak could be added that would look for the word fontspec or math­spec instead, which would make the com­ment unnec­es­sary, though you’d have to give it more lines.)

    • Excel­lent script, Kevin. I’m in the midst of a move right now, so I’m not in much of a posi­tion to test this (hence the slow replies on this blog and the forum!), but I’m going to give this a spin in the near future. Thanks!

  3. Oops, I should have tested my script. While it worked fine as if for nor­mal usage, if you want to use it con­junc­tion with the LatexBox plug-in, it’s bet­ter to have it as:

    #!/bin/bash
    file="$1"
    if head -n 5 "$file" | grep -i -q 'xelatex' ; then
        xelatex --interaction=batchmode --file-line-error --synctex=1 "$file"
    else
        pdflatex --interaction=batchmode --file-line-error --synctex=1 "$file"
    fi 
    

    Also, you need to remove or com­ment out the fol­low­ing lines from ~/.vim/ftplugin/latex-box/latexmk.vim (around line 60 or so).

        let l:options .= " -e '$pdflatex =~ s/ / -file-line-error /'"
        let l:options .= " -e '$latex =~ s/ / -file-line-error /'"
    

    (Prob­a­bly there’d be a way around that, but I’m too lazy to fig­ure it out.)

    Also, I’ve fig­ured out an answer to my own ques­tion above about “smart quotes”. Here’s my own solu­tion. I put the fol­low­ing in my ~/.vim/ftplugin/tex.vim file. It causes a hit­ting the dou­ble quote sign to yield two back­ticks fol­low­ing a line break, space, open­ing bracket or amper­sand, to keep it as a dou­ble quo­ta­tion mark after a back­lash (for accents) to yield two apos­tro­phes else­where. Sim­i­larly for a sin­gle quo­ta­tion mark.

    function! s:TexQuotes()
        let insert = "''"
        let left = getline('.')[col('.')-2]
        if left =~ '^\(\|\s\|{\|(\|\[\|&\)$'
        let insert = '``'
        elseif left == '\'
        let insert = '"'
        endif
        return insert
    endfunction
    inoremap  " =TexQuotes()
    function! s:TexSingQuotes()
        let insert = "'"
        let left = getline('.')[col('.')-2]
        if left =~ '^\(\|\s\|{\|(\|\[\|&\)$'
        let insert = '`'
        endif
        return insert
    endfunction
    inoremap  ' =TexSingQuotes()
    

    The basic idea for that comes from the Vim-AUCTeX plu­gin, though I’ve actu­ally improved on it on my own. I’m cur­rently work­ing on my own per­son­al­ized “franken-plugin” with parts taken from latex-box and parts taken from Vim-AUCTeX, which is also a very nice plu­gin. It’s sort of in between the LaTeX box and the LaTeX suite in terms of fea­tures and com­plex­ity. The code for it is also very well doc­u­mented inter­nally so you can steal parts out of it fairly easily.

  4. If i use the setlocal formatoptions+=wa from your list­ing above things get really messy if I add a \footnote{}. Which hap­pens fairly often in aca­d­e­mic papers. ;)

    I’m still search­ing for a solution.

  5. setlocal textwidth=78 does the trick :)

  6. Hi Max,

    You are right that you need a tex­twidth set­ting in there some­where, else vim won’t know where/when to break the lines. You can still run into trou­ble in var­i­ous ways if you leave a space at the end of a line when you didn’t mean to (since you’ll end up join­ing lines on acci­dent). I’m not sure exactly which prob­lem you were talk­ing about with foot­notes, but I’m very glad you solved it.

  7. Thanks for the excel­lent post! I was look­ing to set up a good (g)Vim LaTeX envi­ron­ment, and LaTeX Box seems to do every­thing I want. The con­tin­u­ous pre­view fea­ture, while not strictly nec­es­sary, is espe­cially use­ful (and it works fine with Evince too, for what it’s worth).

    • Glad to hear it. I think Latex-box is an under­rated plu­gin. I’m glad to hear you are lik­ing it.

      There are few occa­sions where I need the con­tin­u­ous pre­view, but on those few occa­sions where I do, it is really nice. Thanks for let­ting me know it works with Evince.

  8. In your descrip­tion, the viewer short­cut ‘\lv’ does not work for me, as appar­ently ‘v’ is inter­preted as the Vim com­mand to switch to visual mode rather than a part of ‘\lv’. How does one fix this? (I imag­ine that chang­ing the leader won’t help…)

  9. Hi Dmitrii, Hmn. I’m not quite sure what to tell you about that. I don’t use that com­mand. I just checked and while the :LatexView com­mand is get­ting called, it isn’t open­ing up my pdf viewer for some rea­son. But I don’t think I’m hav­ing the prob­lem you are. I’m not versed enough in VimL to know how to fix the problem.

    One ques­tion: does \ll com­pile for you? I might have an idea what is going on if none of the LaTeX-Box com­mands are work­ing for you.

  10. I recently install latexbox on macvim but help latexbox works but none of the com­mand like :LatexView do. Do you have any ideas ?

  11. Rafael Nonato says:

    Hi. Thanks for this tuto­r­ial. I’m try­ing to ditch latex-suite in favor of latex-box. And I would love to be able to make the last line on your tex.vim work, but I get this error:

    Error detected while pro­cess­ing /Users/rafaelnonato/.vim/ftplugin/tex.vim: line 8: E488: Trail­ing characters:

    Any ideas?

  12. Rafael Nonato says:

    And then I can’t get the trail­ing char­ac­ters to come up here, but they are line 9 of your tex.vim

  13. Another solu­tion is to use ATP plu­gin for Vim, you can check its fea­ture list here: http://​atp​-vim​.source​forge​.net/​f​e​a​t​u​r​e​s​.​s​h​tml

  14. Hi,

    first of all, thanks very much — this is a very help­ful post.

    i have a few small issues, but it’s already made things work bet­ter for me, so i’m well pleased.

    my small prob­lem is that i can’t get the calls to the to work in the vim.tex map­pings to work.

    i am pretty sure that the vim.tex is work­ing, as i am able to use the ‘[[‘ com­mand to open an envi­ron­ment = ‘\begin{‘. i have fudged the close envi­ron­ment by map­ping ’]]’ to ‘/end{‘, but obvi­ously this isn’t quite as nice … and i haven’t got access to the nice f# mappings.

    (the line-link with skim also works … thanks that’s a neat trick)

    best regards

    mj

Leave a Reply