I just setup this mapping for my latex development:

nnoremap <buffer> <LocalLeader>o :make %:r.pdf <Bar> !open %:r.pdf<CR><CR><CR>

But I wondered about checking if :make fails before running !open, so that I don't open an old version for some reason.

I know if it were :!make, I could check v:shellerror; however, I cannot find any documentation on :make errors outside of what's put in the quickfix list.

  • Vim seems to set v:shell_error for :make. Is this question about Neovim specifically?
    – Matt
    Aug 22, 2020 at 15:51
  • 1
    You just got Yahtzee! on your reputation! 😁
    – filbranden
    Aug 22, 2020 at 15:53
  • 1
    @Matt The issue is with the | tee in 'shellpipe', it basically always returns 0 and masks the error return code of the make program... I'll post an answer shortly.
    – filbranden
    Aug 22, 2020 at 15:54
  • @Matt no, I don’t use neovim at the moment
    – D. Ben Knoble
    Aug 22, 2020 at 16:04

2 Answers 2


Vim will set v:shell_error with a :make invocation, same as it does for other ways it executes external commands using the shell.

The most likely reason why you're not seeing the error code of the make execution in v:shell_error (and always seeing it return 0) is that on Unix platforms and most common shells Vim defaults to piping the output of execution of 'makeprg' through the tee program, in order to have it both displayed on the terminal and saved to a file which gets loaded into the quickfix buffer.

This is controlled by the 'shellpipe' option, which defaults to 2>&1| tee on most Unix platforms.

You can override this behavior (but not get to see the output of your 'makeprg' in the terminal) by overriding it not to include a pipe to tee. For example:

:set shellpipe=>%s\ 2>&1

Then after running :make you'll get v:shell_error to store the error return of the external command.

If you're using bash as your shell and your 'makeprg' is a single program (rather than a pipeline), you can also use the following to run it through tee and still capture the exit code of the 'makeprg':

:let &shellpipe = ' 2>&1| tee %s; exit ${PIPESTATUS[0]}'
  • Hm this is interesting. Certainly makes it more complicated! May not be worth it. But you’ve certainly answered the question
    – D. Ben Knoble
    Aug 22, 2020 at 16:18

Another option is to try to parse Quickfix List itself. For example,

" check if the last line contains "Error" or "Stop"
function! QfError() abort
    return getqflist()[-1].text =~# 'Error\|Stop'

Of course, such stuff is very fragile, as it relies on &makeprg output having a known format.

Your Answer

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

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