1

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 '20 at 15:51
  • 1
    You just got Yahtzee! on your reputation! 😁 – filbranden Aug 22 '20 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 '20 at 15:54
  • @Matt no, I don’t use neovim at the moment – D. Ben Knoble Aug 22 '20 at 16:04
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 '20 at 16:18
0

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'
endfunction

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, privacy policy and cookie policy

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