Vim for LaTeX

Posted to site: 10/02/19

As a maths stu­dent, I am of­ten us­ing LaTeX to type up my as­sign­ments or write notes for my classes. Given its power and flex­i­bil­ity, I also use it for al­most all doc­u­ments that I write these days, such as let­ters and CVs. Before now, I had pre­dom­i­nantly been us­ing TexMaker and later Overleaf when I switched to Ubuntu. These were great LaTeX ed­i­tors whose fea­ture set I prob­a­bly never ex­hausted, but they did­n’t quite fit with my new sys­tem. I wanted an ed­i­tor that was light­weight, highly cus­tomis­able, ran lo­cally and could seam­lessly up­date a pdf while I typed. Vim was the ob­vi­ous choice.

This change in ed­i­tor was mo­ti­vated by my switch from Ubuntu with the XFCE desk­top en­vi­ron­ment to Arch Linux with the i3 win­dow man­ager for my main OS. This was quite the cul­ture shock and took a while to get every­thing up and run­ning and even longer to get it con­fig­ured how I wanted. But, now I have a work­ing sys­tem that’s op­ti­mised for my per­sonal work­flow and looks the way I want (click here for a small al­bum of some screen­shots of my desk­top). I wanted a text ed­i­tor that would match the con­fig­ura­bil­ity of the rest of my desk­top, prefer­ably run­ning in the ter­mi­nal.

Vim is an un­ques­tion­ably pow­er­ful text ed­i­tor which runs on prac­ti­cally any com­puter and is fa­mously con­fig­urable. The main down­side of Vim is ob­vi­ously the learn­ing curve. But, with vimtutor and a whole host of re­sources avail­able on­line, I de­cided it was worth the ef­fort. More­over, LaTeX seemed to be the per­fect gate­way drug to learn­ing Vim. LaTeX is a fan­tas­tic type set­ting lan­guage but its syn­tax is aw­fully clunky and repet­i­tive so it seemed highly sus­cep­ti­ble to Vim’s edit­ing power.

Vim plu­g­ins for LaTeX

There are a num­ber of great Vim plu­g­ins for LaTeX, all with their re­spec­tive pros and cons. Some plu­g­ins are highly opin­ion­ated and turn Vim into a fully fea­tured LaTeX ed­i­tor with no con­fig­u­ra­tion needed. Oth­ers pro­vide ba­sic func­tion­al­ity spe­cific to LaTeX edit­ing but leave other fea­tures such as snip­pets and au­to­com­ple­tion to other plu­g­ins. This ad­heres more to the UNIX phi­los­o­phy of do one thing and do it well” and so was my pref­er­ence. I’ll give a quick-sum­mary of the main op­tions here.

Vim-LaTeX/LaTeX-Suite

LaTeX-Suite is a fully fea­tured plu­gin for Vim with an enor­mous fea­ture set, great con­fig­ura­bil­ity and fan­tas­tic doc­u­men­ta­tion. If you want a plu­gin that pro­vides all the fea­tures of a con­ven­tional LaTeX ed­i­tor along­side the power of Vim, this is the plu­gin for you. How­ever, I strug­gled to setup au­to­matic pre­views with my PDF viewer mupdf and it does­n’t use latexmk, which greatly eases the pain of LaTeX com­pi­la­tion. More­over, given its ob­jec­tive, it is not very mod­u­lar and so does­n’t play well with other plu­g­ins that can pro­vide this func­tion­al­ity.

vim­tex

In the end I de­cided to use vim­tex for my main plu­gin. It builds on the lan­guage of Vim by pro­vid­ing a num­ber of LaTeX spe­cific text ob­jects and mo­tions for use in your edit­ing. More­over, vim­tex was very easy to setup with my PDF viewer such that the viewer was up­dated every time I saved my tex file. Also, I can use <localleader>lv to do a for­ward search and show the part of the doc­u­ment I’m cur­rently edit­ing in my PDF viewer. This com­pi­la­tion is done seam­lessly through latexmk and er­rors are dis­played in­side a Vim buffer. The main fea­ture miss­ing from vimtex is the lack of a full snip­pet fea­ture but this can eas­ily be han­dled by a ded­i­cated plu­gin such as neosnippet.


Autocompilation with vimtex
Autocompilation with vim­tex

vim-tex-fold

vim-tex-fold is a great lit­tle plu­gin that au­to­mat­i­cally folds up sec­tions and spec­i­fied en­vi­ron­ments within your tex file. This makes nav­i­gat­ing about your doc­u­ment much quicker and eas­ier. The great thing about this plu­gin is it al­lows you to spec­ify cus­tom fold points with com­ments, al­low­ing you to fold up any sec­tion of your doc­u­ment. This can help clean up the messy pre­am­ble that of­ten gets in the way when edit­ing LaTeX files.


LaTeX file fully folded up by Vim
LaTeX file partially folded by Vim
Folding LaTeX files in Vim with vim-tex-fold for eas­ier edit­ing

Custom set­tings

All of my cus­tom set­tings are kept in ftplugin/tex.vim so that I don’t clut­ter up my vimrc with a load of file­type-spe­cific set­tings and map­pings. To make sure all these set­tings work just put

filetype plugin syntax on

in your vimrc. For my full set­tings please see my dot­files, here are the most im­por­tant ones.

These two lines make sure vim­tex opens up mupdf and starts auto-com­pil­ing when the ed­i­tor starts.

let g:vimtex_view_method = "mupdf"
autocmd VimEnter *.tex VimtexCompile

This line turns on spell check.

set spell spelllang=en_gb

This line cre­ates a map­ping for fold­ing every­thing up in the doc­u­ment but leav­ing the cur­rent line vis­i­ble. We will use it in some later map­pings.

nnoremap zl zMzv

Custom map­pings

These cus­tom map­pings fill the gap that vim­tex leaves be­hind. I of­ten find my­self typ­ing the same LaTeX code over and over again at which point I write a map­ping which au­to­mates this process for me. Most of these are just mapped in in­sert mode be­cause they are short­cuts for com­mands I want to in­sert. They are all pre­ceded by my lo­cal leader , which was cho­sen be­cause when writ­ing text a comma is al­most al­ways fol­lowed by a space so this pre­vents ac­ci­den­tal mis­use.

Placeholders

Many tex com­mands use mul­ti­ple ar­gu­ments re­sult­ing in con­stant mode switch­ing in or­der to move be­tween brack­ets. This quickly be­came an an­noy­ance. To al­le­vi­ate this is­sue, I have used place­hold­ers, namely <++>, which are in­serted by the map­pings in places where I will usu­ally want to jump. Then by press­ing ,, I can nav­i­gate to the next place­holder af­ter the cur­sor and start typ­ing in its place. This is im­ple­mented in the fol­low­ing Vimscript which I have adapted from Luke Smith.

inoremap <leader><leader> <Esc>/<++><Enter>zl"=c4l
vnoremap <leader><leader> <Esc>/<++><Enter>zl"=c4l
map <leader><leader> <Esc>/<++><Enter>zl"=c4l

For ex­am­ple, I have cre­ated the fol­low­ing map­ping

inoremap ,fr \frac{}{<++>}<++><Esc>Fcla

which can be used to quickly in­sert a frac­tion in the fol­low­ing way.


Fractions mapping example
,fr map­ping in ac­tion

This can also be used to quickly in­sert bold, em­phatic or italic text.

inoremap ,bf \textbf{}<++><Esc>T{i
inoremap ,em \emph{}<++><Esc>T{i
inoremap ,it \textit{}<++><Esc>T{i

Environments

When I first started us­ing Vim for LaTeX, cre­at­ing en­vi­ron­ments was a pain. In pre­vi­ous ed­i­tors, start­ing an en­vi­ron­ment would au­to­mat­i­cally cre­ate the ap­pro­pri­ate clos­ing com­mand. Not so in Vim. The so­lu­tion was some more map­pings, us­ing place­hold­ers where en­vi­ron­ments took op­tional ar­gu­ments.

inoremap ,t \begin{theorem}<Enter><Enter>\end{theorem}<Esc>ki
inoremap ,T \begin{theorem}<Enter>[]<++><Enter>\end{theorem}<Esc>?\]<Enter>i
inoremap ,p \begin{proof}<Enter><Enter>\end{proof}<Esc}ki

For the most part this worked but some­times I wanted to in­sert an en­vi­ron­ment that I did not use suf­fi­ciently of­ten to war­rant its own map­ping. So I cre­ated the fol­low­ing map­pings to cre­ate ar­bi­trary en­vi­ron­ments, po­ten­tially with op­tions, by typ­ing their name fol­lowed by ,be or ,BE.

inoremap ,be <Esc>^y$^i\begin{<Esc>$a}<Enter>;<Enter>\end{}<Esc>hp?\;<Enter>xi
inoremap ,BE <Esc>^y$^i\begin{<Esc>$a}[]<Enter><++><Enter>\end{}<Esc>hp?\]<Enter>i

Note I am cur­rently just yank­ing the en­vi­ron­ment name but I should prob­a­bly yank it to a spe­cific reg­is­ter to avoid con­flict­ing with any text I am cur­rently copy­ing.


Environments mapping example
,T and ,be map­pings in ac­tion

Visual mode map­pings

When typ­ing up notes I of­ten find my­self us­ing the \underbrace{}_{} com­mand to la­bel terms in an equa­tion. I tend to write out the whole equa­tion first, and then come back and la­bel it up, so this was the per­fect time to use a vi­sual mode map­ping. For this I am us­ing Tim Pope’s vim-sur­round plu­gin. I have cre­ate two map­pings, one for an­no­tat­ing with text and one with more maths.

vmap ,ut SBi\underbrace<Esc>l%a_{\text{}}<Esc>hi
vmap ,um SBi\underbrace<Esc>l%a_{}<Esc>i

Underbracing mapping example
,ut map­ping in ac­tion

Next steps

The power of Vim is in its cus­tomis­abil­ity so as I con­tinue writ­ing LaTeX doc­u­ments I will keep an eye out for com­monly typed phrases and cre­ate new map­pings to speed up my work­flow. While I could use a pre-com­piled snip­pet li­brary, I find it bet­ter to cre­ate cus­tom map­pings that pri­ori­tise speed­ing up the code that I, my­self, re­peat­edly write.

One mi­nor an­noy­ance with Vim is that I have to close my PDF viewer every time I exit Vim (although some may view this as a bonus). This could be fixed by us­ing Vim’s autocmd VimLeave fea­ture which can run ar­bi­trary Vim com­mands be­fore leav­ing the ed­i­tor. I may also get Vim to send a sig­nal to my win­dow man­ager to re­move gaps be­tween win­dows on en­ter­ing a LaTeX file, to max­imise screen real es­tate.

Having seen the power of text edit­ing in Vim and start­ing to learn its lan­guage, I would like to use Vim to edit other code. I am cur­rently ex­tend­ing the code for my Mandelbrot pro­ject which is writ­ten in C++. In or­der to ef­fec­tively use Vim as my ed­i­tor for this, I will need a lint­ing and auto-com­ple­tion en­gines and prefer­ably a de­bug­ger built into Vim.

Useful re­sources