UPDATE: I added a solution to my gripe about LaTeX-suite’s use of the back tick below.
This is part three of my multi-part series on setting up Vim as a writing environment for LaTeX. Last week I wrote a couple 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 writing papers in LaTeX using Vim, you’ll want to get a plugin to help. You are going to want to compile your document from within Vim (for a long time I opened TeXShop just to compile my papers; it wasn’t efficient). And you’ll want to be able to set up citation completion. Plus, there are a number of key bindings and shortcuts that can make your LaTeX composition easier.
The plugin
There are a number of LaTeX plugins you can choose from. The most popular is probably the LaTeX-suite. That is a very complete plugin—it includes everything, even a number of the package files you might use in your document. I used to use this plugin, but after looking around at other options, I decided to bail on it.
There were three reasons that lead me to look for other options. First, I realized that customizing the plugin (to get the citation completion to work, to get my papers to compile correctly) was entirely too much work. Second, it looks like the plugin is no longer supported by a developer—the files were updated the last time in 2004. That makes me slightly uncomfortable. Third, some of the key bindings drove me crazy. With the LaTeX-suite plugin, the back tick is involved in a number of key bindings. So type `p and it is replaced with \pi. The idea is to make it easier to type Greek letters if you can’t remember the symbols. But the actual effect for me is that any time I needed to write a single quote (which is fairly often), I would need to write the letter, then arrow backward, then type the back tick, then arrow forward. I could probably track down the lines/files to delete in order to eliminate this behavior. 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 plugin. He writes about changing the LaTeX-suite leader over on his blog. Here is the short and sweet version: put let g:Tex_Leader=',' somewhere in your .vimrc file. This will change the leader (for LaTeX-suite specific commands, not for all Vim commands) from the back tick to the comma. You could use anything you like if you use the comma for something else. So instead of `b inserting \beta, you could insert that with ,b.
After looking around, I decided to try out, and then really liked, the LaTeX-box plugin. This is a much more minimal plugin, but I think it works much better (at least for me). The plugin offers all the things I need: it lets me compile my papers and it gives me citation completion abilities. And it includes some bonus features I didn’t expect but quite like (e.g., a key mapping to close the last opened environment, and one to generate a table of contents for navigation purposes).
After using the plugin for a couple of weeks (and interacting with the developer, who is really great, by email), I decided to stick with the LaTeX-box plugin and not try some of the other options like auctex.vim and the Automatic TeXPlugin. If you are looking for a Vim LaTeX plugin, give this one a shot.
The developer chose to use the Vimball format for packaging the LaTeX-box plugin, which means trying it out couldn’t be easier. (You’ll want to remove any other LaTeX plugins you have installed. If you have the LaTeX-suite installed, this is a lot of files. I downloaded that plugin just so I could see all the files to delete. This was moderately tedious, but worth it.)
Steps to install the plugin:
- Download it first: you can get the plugin at http://www.vim.org/scripts/script.php?script_id=3109.
- Open the LatexBox.vba file with Vim, MacVim, or gVim.
- Once you open the file, in normal mode type
:so %. This tells Vim to source the current file.
That’s it. The Vimball format means you can uninstall the plugin by simply opening Vim (any file will do here) and typing :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 especially if you try to uninstall it), you’ll come to appreciate Vimballs pretty quickly.
Basic plugin functionality
Latex-box does two things quite well: LaTeX compilation and citation completion. It has some other features, but those are the two main things this fairly minimal plugin was designed to do.
Latex-box compiles your paper with latexmk. To compile your paper, when you are in normal mode hit <leader>ll. The default <leader> is the backslash. So to compile 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 automatically be compiled. What’s more, latexmk is setup to compile as many times as necessary to resolve all issues. If you have section references and a bibliography, if you compile by hand you have to run latex, run bibtex, then run latex at least twice more. Latex-box (thanks to latexmk) will take care of all of that for you. One \ll will produce a complete paper.
There are a handful of other compilation commands you might want to use with latex-box. Typing \lv should open the viewer you want (more on that in the next section). If you want to stop latexmk, type \lk. If you want to clean out the cruft files that compilation creates, hit \lc. If you want to clean out all the files besides your .tex file (pdf file included), hit \lC.
One feature I really like is the table of contents command (you’ll need to have compiled your paper and not gotten rid of the .toc file for this one to work): hit \lt and you will get a vertical split window over on the left of your main Vim window. It will list all the sections of your paper. Navigate to the one you want and hit Enter and the split will disappear and you’ll go to that section in your .tex file. (In this split window you can use all the basic Vim commands—so if section 7 is on line 10, type 10G and you’ll go directly to that line of the window.)
Latex-box uses the Omni Complete function to do citation and reference completion. So if you type \cite{ then hit Control+x then Control+o, you’ll get a nice little pop up window with all your possible citations in it. Scroll down to the one you want using the arrow keys. (You may have to hit Enter, sometimes I seem to, other times I just hit the space bar or close the }.) If you type the first few letters of your cite key the completion list will be more manageable. You can also do reference completion: hit the Omni Complete keys in a \ref{sec: environment and you’ll get a list of all your sections (if you gave them labels via a \label{sec:section_name} command, of course).
.vimrc settings
There are a couple of options you can set with the Latex-box plugin. Two that I set govern the behavior of Latexmk, which Latex-box uses to compile your tex file. I use Skim as my pdf viewer on the Mac (for these purposes at least). I primarily like Skim for use with Latex-box because it can auto-update and it works with SyncTeX. If you run latexmk with the right options, then whenever you make changes to your file and save them, latexmk recompiles your document. If you configure your pdf viewer right, you can see the changes right away. (You can find out more about latexmk’s options by looking at this documentation).
So I put the following 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 monitor it continuously. 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 running, the change will be made automatically to the pdf (this is especially nice if you are using SyncTeX, so you can quickly go to that section of the pdf without tracking it down manually.
Latex-box offers nice citation completion capabilities. It already knows where your bib file is (if it is in one of the standard locations), so you don’t have to specify that the way you do with the LaTeX-suite plugin. To use citation (or \ref completion), you need to use the Omni Complete function of Vim. To do that, you hit Control+X Control+O.
I make two changes to my ~/.vimrc to make citation completion run more smoothly. First, I remap the F9 key to do the Omni Complete stuff. I use completion enough to make that well worth my while (why hit two complicated keys when I can hit one?). The other change is to the cite pattern. By default, Latex-box only knows that a few citation commands are citation commands. 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 citation completion. And if you use practically any of the BibLaTeX citation commands (e.g., \Cite) you won’t be able to use citation completion. A slight change will make all these work, however. Just add the second line below to your ~/.vimrc to make this work.
inoremap
let g:LatexBox_cite_pattern = '\c\\\a*cite\a*\*\?\_\s*{'
Settings in a .vim/ftplugin/tex.vim file
There are some key mappings that I want to use, but that I don’t need to be available for every document I write. I use Omni Completion for other kinds of files, so I put that mapping in my ~/.vimrc. But I won’t use commands to close a LaTeX environment in any other kind of file.
So I created a file at ~/.vim/ftplugin/tex.vim. This file takes settings just like your ~/.vimrc file does, but it only applies them to .tex files. The following (save the first one) all come directly from the documentation for this plugin; the first is just my preference. 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"
Elsewhere I set my lines to hard wrap at 72 characters (at the closest word). In what follows, 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 indicates that the paragraph continues; a line that ends in anything other than a space indicates the end of the paragraph. You can get away with hard wrapping in LaTeX because LaTeX only counts a new paragraph if it encounters a \ or a blank line. In normal mode, type :h fo-table for more on these options.
The rest make using environments easier: [[ will insert a \begin{ and ]] will insert \end{env} for whatever environment was opened most recently. If you put your cursor (in normal mode) on the environment 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 commands. (Switch to visual mode by hitting ‘v’ in normal mode. This is kind of like holding down your mouse button and selecting 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 backslash and your cursor will be put in front (so this would be transformed to \^{this}, where the caret represents your cursor). Do the same and hit Shift+F7 and the selection will be wrapped in \begin{} \end{} tags.
The last one is very nice. If you use Skim (which supports SyncTeX for syncing your .tex and .pdf files), then if you include this line, while latexmk is running 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 sensitive as the TeXShop version: if you use soft wrapped lines (one line per paragraph, say), then this will take you to the start of the paragraph. But if you hard wrap your lines and keep them shorter (like 72 or 80 characters), this will take you right to the word under the cursor. I don’t know how to generalize this if you use Ubuntu or something, 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 accommodate that. Just how you set it up depends on how often you use XƎTeX v. LaTeX. In short, you need to create a file to tell latexmk that you are using XƎTeX. If you use XƎTeX for all your LaTeX needs, then you can create this file in your home directory. Just call it .latexmkrc. If you only want to use XƎTeX for some of your projects, don’t create that file; instead, create a file in the directory of your XƎTeX project called either latexmkrc or .latexmkrc. Either name is fine.
Regardless of where you put that file, it will have the same contents: a single line that says
$pdflatex = 'xelatex %O %S'
[UPDATE: Be sure to check out Kevin’s clever script below. If you run this, it will determine whether you plan to use xelatex or not and will avoid the need for you to create a latexmkrc file on a per-project basis. Very handy.]
SyncTeX
If you want to use SyncTeX you need to do two things. First, you need to insert a line in the prologue of your paper:
\synctex=1
Second, you need to set up a pdf viewer that has SyncTeX capabilities. I’m not the man to ask about viewers other than Skim (and I don’t even have too many answers about it). If you’ve specified an appropriate viewer in your .vimrc (above), and if you’ve put the appropriate key mapping 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 SyncTeX 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 hoping to look into it in the coming weeks, and if I figure it out I’ll write about it.
Until then, I can’t recommend the Latex-box plugin enough. I think it is an efficient LaTeX plugin for Vim that does all the things I need it to. If your needs are like mine, I think you’ll probably like it quite a bit.

Regarding the backtick issue, a lot of LaTeX editors (Kile, Texmaker, Texworks, LyX, Emacs with AUCTeX, TeXnicCenter if memory serves, probably some others) have (the equivalent of) a “smart quote” feature, which, depending on context, automically change a double quote to either two backticks or two apostrophes (or even the Unicode “ and ”) depending on context, and similarly will change an apostrophe to a backtick at the beginning of a word. That would free up using an explicit backtick for other purposes. Do you know of any way of getting that with Vim? (I think I might be able to do it with autokey, but I’d prefer to do it from within vim itself.)
As for SyncTeX forward/reverse search, this supported by Okular on linux (and will be supported by the next version of evince). SumatraPDF supports this on Windows. I had forward/reverse working in both directions between Okular and the vim LaTeX suite (e.g., \ls in gvim to find the matching spot in Okular), shift click in Okular to jump to the matching spot in the source. If I can remember how, I can post instructions if anyone is interested. Should be possible to get it working in the other direction with skim, but don’t ask me how.
It should also be possible to configure things so that latexmk always calls –synctex=1 when compiling so you don’t need \synctex=1 in your source file.
Here’s a trick you to make it easy to tell LaTeXmake to use xelatex or pdflatex. I wrote a shell script that will read the first 5 lines of an input file and then either call xelatex or pdflatex (I called it xepdflatex.sh) depending on whether or not it includes the phrase ‘xelatex’ 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" fiAnd then in my primary .latexmkrc in my home directory:
(The important thing here is the first line, which tells it to use the script as its form of pdflatex.)
Then instead of making separate latexmkrc files for each project, I just stick a comment line:
at the beginning of any file that needs to be processed with xelatex.
(A tweak could be added that would look for the word fontspec or mathspec instead, which would make the comment unnecessary, though you’d have to give it more lines.)
Excellent script, Kevin. I’m in the midst of a move right now, so I’m not in much of a position 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!
Oops, I should have tested my script. While it worked fine as if for normal usage, if you want to use it conjunction with the LatexBox plug-in, it’s better 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" fiAlso, you need to remove or comment out the following 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 /'"(Probably there’d be a way around that, but I’m too lazy to figure it out.)
Also, I’ve figured out an answer to my own question above about “smart quotes”. Here’s my own solution. I put the following in my ~/.vim/ftplugin/tex.vim file. It causes a hitting the double quote sign to yield two backticks following a line break, space, opening bracket or ampersand, to keep it as a double quotation mark after a backlash (for accents) to yield two apostrophes elsewhere. Similarly for a single quotation 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 plugin, though I’ve actually improved on it on my own. I’m currently working on my own personalized “franken-plugin” with parts taken from latex-box and parts taken from Vim-AUCTeX, which is also a very nice plugin. It’s sort of in between the LaTeX box and the LaTeX suite in terms of features and complexity. The code for it is also very well documented internally so you can steal parts out of it fairly easily.
If i use the
setlocal formatoptions+=wafrom your listing above things get really messy if I add a\footnote{}. Which happens fairly often in academic papers.I’m still searching for a solution.
setlocal textwidth=78does the trickHi Max,
You are right that you need a textwidth setting in there somewhere, else vim won’t know where/when to break the lines. You can still run into trouble in various ways if you leave a space at the end of a line when you didn’t mean to (since you’ll end up joining lines on accident). I’m not sure exactly which problem you were talking about with footnotes, but I’m very glad you solved it.
Thanks for the excellent post! I was looking to set up a good (g)Vim LaTeX environment, and LaTeX Box seems to do everything I want. The continuous preview feature, while not strictly necessary, is especially useful (and it works fine with Evince too, for what it’s worth).
Glad to hear it. I think Latex-box is an underrated plugin. I’m glad to hear you are liking it.
There are few occasions where I need the continuous preview, but on those few occasions where I do, it is really nice. Thanks for letting me know it works with Evince.
In your description, the viewer shortcut ‘\lv’ does not work for me, as apparently ‘v’ is interpreted as the Vim command to switch to visual mode rather than a part of ‘\lv’. How does one fix this? (I imagine that changing the leader won’t help…)
Hi Dmitrii, Hmn. I’m not quite sure what to tell you about that. I don’t use that command. I just checked and while the
:LatexViewcommand is getting called, it isn’t opening up my pdf viewer for some reason. But I don’t think I’m having the problem you are. I’m not versed enough in VimL to know how to fix the problem.One question: does
\llcompile for you? I might have an idea what is going on if none of the LaTeX-Box commands are working for you.I recently install latexbox on macvim but help latexbox works but none of the command like :LatexView do. Do you have any ideas ?
Hi. Thanks for this tutorial. I’m trying 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 processing /Users/rafaelnonato/.vim/ftplugin/tex.vim: line 8: E488: Trailing characters:
Any ideas?
And then I can’t get the trailing characters to come up here, but they are line 9 of your tex.vim
Another solution is to use ATP plugin for Vim, you can check its feature list here: http://atp-vim.sourceforge.net/features.shtml
Hi,
first of all, thanks very much — this is a very helpful post.
i have a few small issues, but it’s already made things work better for me, so i’m well pleased.
my small problem is that i can’t get the calls to the to work in the vim.tex mappings to work.
i am pretty sure that the vim.tex is working, as i am able to use the ‘[[‘ command to open an environment = ‘\begin{‘. i have fudged the close environment by mapping ’]]’ to ‘/end{‘, but obviously 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