I am new to Vim and I would like to make a key binding to compile my LaTeX source. I have the following

autocmd FileType tex :nnoremap <buffer> <F5> :!pdflatex %<CR>

which is working very well but I would like it to run in the background. I know there are options with <silent> but I can't make them work.


3 Answers 3


If you just want a non-disruptive process to run, consider tpope's Dispatch plugin: if you have a makeprg setup well for LaTex, you could use it's :Make; otherwise, you'll want to :Start pdflatex ....

To silence a mapping, use nnoremap <silent> .... But note that this just prevents echoing of the simulated characters being typed.

To silence a command, do :silent[!] command. With !, all error messages are suppressed.

  • Could you provide an example with :silent[!] ?
    – user27022
    Feb 20, 2020 at 18:06
  • @Dave :silent! make for example
    – D. Ben Knoble
    Feb 20, 2020 at 18:13

You can use Vim's job_start() function to run a command asynchronously. This does not require any plugins, but does require Vim to be compiled with the +job feature (you can check this by running the :version command).

Here's a long one-liner to apply your command:

autocmd FileType tex :nnoremap <silent> <buffer> <F5>
    \ :let b:job = job_start(['/bin/sh', '-c', 'pdflatex ' . expand('%:p')])<CR>


  • The pdflatex command only works if your tex file is in Vim's current working directory. So you may want to consider using latexmk instead, which provides a -cd option.

  • I've noticed that in some cases, job_start() will slightly mess up the screen. If this happens, you may want to add a callback function to redraw the screen (see this answer to a related question).

  • 2
    job_start is just the start. We should also register callback for filling in the quickfix list, and taking care of the execution end, and also failures at the start. In the end, this is what plugins do. Feb 22, 2020 at 8:02

The way I like to do this is by using tmux to send the compilation command to another terminal. I like this method because it behaves as if you had typed the command in that terminal yourself.

Add this to your .vimrc (note this code uses latexmk instead of pdflatex):

function! TmuxSend()
    let tex_file = expand('%:p')
    let tex_cmd = 'latexmk -pdf -interaction=nonstopmode -cd ' . tex_file
    let tmux_cmd = 'tmux send-keys -t vim_output.0 "' . tex_cmd . '" ENTER'
    let output = system(tmux_cmd)   

autocmd FileType tex :nnoremap <silent> <buffer> <F5> :call TmuxSend()<CR>

Now, open another terminal and create a tmux session named "vim_output": tmux new-session -s vim_output. Now, when you press F5 in Vim, the latexmk command will be run in the terminal you just created.

Your Answer

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