I have the following code in my vimrc to compile my latex documents with <F5>:

map <F5> :write <Bar> :if expand("%") == "body.tex" <bar>
:exe ':!arara -v "main.tex"' <cr>
:endif <cr> <bar> :!arara -v % <cr> :endif <cr>

(Line breaks added purley for legibility, no linebreaks in my original code.)

I sometimes separate my latex documents in one containing the preamble, called "main.tex", and one containing the text, called "body.tex". If that's the case I want arara to run on the file called "main.tex", otherwise I want it to run on the file I'm writing on itself. None of this matters to the question I'm asking, I just wanted to explain what I'm doing here.

Oddly enough, this code is working, and it only works as intended if I keep it this way. A plausible assumption would have been that the following code would have been sufficient:

map <F5> :write <Bar> :if expand("%") == "body.tex" <bar>
:exe ':!arara -v "main.tex"' <bar> 
:else <bar> :!arara -v % <bar> :endif <cr>

Here, vim complains about :else outside of :if if I'm in a file not called "body.tex", and if I'm within body.tex, I have to press enter to run arara, and have to close the if manually by entering :endif.

You'd also expect vim to complain about the two occurrences of endif in a single if command in the first code, and for the first one to be utterly redundant.

Can anybody shed some light on the exact syntax that I'm dealing with here? Vim help hasn't been a lot of actual help on this.

  • I would start with making this whole mess a function and call that. That is easier to read and understand and can be properly debuged and the :map call is way much simpler. Feb 27, 2018 at 10:16

1 Answer 1


Rather than figuring out what's going on with your existing mappings, it's easier and more readable just to use a function, instead:

nnoremap <F5> :call <SID>compile_latex()<CR>

function! s:compile_latex() abort
  if expand("%") == "body.tex"
    !arara -v "main.tex"
    !arara '-v %'

N.B. The :execute didn't seem to be necessary, so I removed that, too and I used a non-recursive mapping, which you should do unless you have a reason not to.

If you must have a one liner, an expression mapping using a ternary expression might be clearer:

nnoremap <expr> <F5> expand("%") == "body.tex"
  \ ? ':write <bar> !arara -v "main.tex"<CR>'
  \ : ':write <bar> !arara ''-v %''<CR>'

See :help :map-expr for details.

  • 1
    This is indeed much simpler, and I have upvoted this answer, but I'm actually looking for understanding, not only for solutions. The syntax within the if is just completely different from what you'd expect, and I'd like to know what it actually is.
    – sgf
    Feb 27, 2018 at 11:29
  • 1
    Some things are not worth understanding.
    – tommcdo
    Feb 27, 2018 at 11:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.