Latex is a text-based description of document structure. Basic text-formatting is augmented with a number of packages enabling mores specific behaviour. Latex has become a standard in publishing in many fields. But its use is by no means restricted to that. I use Latex for keeping notes, creating presentations and any other kind of formatting where plain-text is not quite enough.

Search for Latex editors and you will find a plethora of Latex specific editors: TexStudio, TexWorks, Lyx and many more. You need look no further than Vim (which is often omitted for some reason). Latex is a plain-text format, which automatically makes it well suited for Vim.

I’ll discuss plugins (which I highly recommend) later, but it is perfectly possible to write Latex in vanilla vim.

Latex in Vanilla Vim

You don’t really need any plugins to write Latex in Vim. Tex highlighting is included. Spell check is important and should be set up, but works without any plugins (I have mine enable with an autocommand when I open a Tex file). Vim is perfectly usable for Latex just like this. There are a couple other built-in features that I think work well in a setup like this: completion and the :make command.

Completion

I regularly find myself using <C-N> completion when writing Latex. Most commands I use, I use more than once per document. Keyword completion is a good-enough solution to reducing the amount of typing required because getting the first few characters of a command (or, a really long word) is enough to make the completion list short and fast to navigate. Even better, <C-N> completion is powerful enough to handle reference completion. I typically keep my .bib file(s) open in other buffers and <C-N> will search these buffers when it looks for a completion. Hey presto, there’s a working bibliography completion!

Building

Exiting Vim to run pdflatex or your favorite compiler isn’t very fun or efficient. Running something like :!pdflatex % is a bit better, but if you can write a simple makefile, Vim can do better. Then you can use the :make which means you can link the compiler output with a quickfix list. If you aren’t going to use a plugin, a simple make file is probably best. But, while we’re on the topic, this is where plugins start to help.

So, why use plugins?

There are a few obviously missing components. Vim only supports Tex highlighting out-of-the-box. Completion is good, but not on the level that TexStudio or TexWorks exist at. Creating a makefile for every small Latex project is over the top. There are a few rough ends integrating Vim commands into the Latex ecosystem.

I have used two plugins extensively. The first is Vim-LaTeX, which provides extensive functionality but doesn’t quite mesh into the Vim ecosystem as well as it could. I moved away from it because of its clunky integration with modern package managers and frustrating auto-expansions. But, do not get me wrong: Vim-LaTeX is a very good Latex plugin.

I started using vimtex. vimtex provides the functionality within Vim-LaTeX which the authors see as vim-like. vimtex provides Latex-specific text-objects, such as within Latex environments and delegates much of the Vim-LaTeX functionality to different plugins.

Now, this article is not a comparison of vim-latex plugins. But I will talk about the features they provide; mostly from the perspective of a vimtex user.

The first command I learned in both is how to compile. I map this to <localleader>ll. Compiling pops up a quickfix window that can be navigated to jump to the faulty source line (well, if you trust the Latex compiler to give you an error on the right line, but that is another topic). I have this window setup to open and close with <localleader>le (Latex errors). Opening a PDF-viewer to see the results should be similarly easy. I have this mapped to <localleader>lv (Latex view).

Completion (Round II)

The section above deals with the overhead of a makefile for short documents. But vim packages provide far more than this. The first is sensible completion. A typical reason I hear for not to switch to Vim for Latex is “because the autocomplete is not as good.” As discussed above, I usually find that <C-N> is plenty enough for Latex. But I’ve written enough Latex that I’m not usually scrounging for commands. vimtex provides an omni-completion (<C-X><C-O>) that can intelligently suggest command completions.

Fitting Latex within Vim

Completion is often a headline feature — and rightly so. But Latex plugins provide many other features. K links to the Latex documentation when in a Latex document. The syntax highlighting is better than the built-in documentation. Navigation commands, such as [[ and ]] to jump between sections or ]m [m to jump between environments.

Vimtex introduces a few good commands: cse changes the surrounding environment, for example if you want to change from an itemize to an enumerate. In insert mode, ]] automatically closes an unclosed environment (i.e. produces the corresponding \end{X} command.

Vim-LaTeX has some good (and some really bad!) auto expansions: typing __ produces _{<cursor is left here>}<++>, which means you can type the subscript you want and then press <C-J> to jump outside of the brackets. I liked some of this functionality so much I kept it when I moved to vimtex. Similarly inspired by latex-suite, I map mma (using iabbrev to prevent words like “comma” expanding) in insert mode to produce:

\begin{align}
    <leave cursor here>
\end{align}<++>

And have several similar mappings for other environments I regularly use. This means I can type mma<Space>, enter the text I want, and press <C-J> to jump to (and delete) the <++> character.

What is my workflow?

Typically, I split the screen vertically in two. One half contains Vim, and the other half contains a PDF viewer with the document I’m writing.

Vim is an editor that works well with different lines. j, k, d, you name it, these commands each work on a line-by-line basis. With that in mind, I highly suggest that you manually break each line (i.e. not using linebreak, but manually pressing <Enter> at the end of each line). Why? Because that means all of these commands actually work well and you’ll find yourself editing text in a more Vim-like way. If each paragraph is a single line of text as far as Vim is concerned, these commands are seriously handicapped. Beyond this, if you type a paragraph per line and use persistent undo, you will find your persistent undo files becoming huge. Essentially, Vim stores your persistent undo information line-by-line: and it stores the whole line every time. If you have lines thousands of characters long, you will find (like I did) that your persistent undo directory uses all your hard disk space very quickly!

Of course, lots of documents are shared, and in my experience, people tend to prefer using a single line per paragraph, so you may be stuck.

Plugin Configurations

I’m not going to go into a huge amount of detail here, just some personal preferences, focusing on vimtex. I like to set:

let g:vimtex_fold_enabled = 1

To turn on code folding for Tex files.

Using:

let g:tex_flavor = 'latex'

Avoids opening an empty .tex file only to have vimtex recognize it as plain Tex rather than Latex.

If you use ALE (or other linting environment supporting Latex), I suggest you disable it for Latex. Many of these linting environments can’t handle 100s of warnings efficiently, and I find that Latex’s warning suites give lots of false warnings.

Conclusion

If you are looking for a Latex editor, look no further, Vim is what you are after. There are a million more ways to edit Latex in Vim than what I’ve talked about here. I don’t have space (nor desire!) to reproduce the documentation for vimtex or Vim-LaTeX, not to mention the other Latex packages I haven’t tried. This article is certainly not a substitute for the excellent documentation these packages have.

I have written 100,000 lines of Latex over the last four years using this setup. I hope this sets you on your way to writing Latex in vim.