Consider the following:
function! RunWithErrorHandling(command) abort let view = winsaveview() let errorOutputFile = tempname() let shellredir_save = &shellredir let &shellredir = '>%s 2>' . errorOutputFile silent execute a:command let &shellredir = shellredir_save if v:shell_error != 0 silent undo echohl ErrorMsg for error in readfile(errorOutputFile) echoerr error endfor echohl None endif call delete(errorOutputFile) call winrestview(view) endfunction command! JsonToDict call RunWithErrorHandling('% ! python -c "import json; import sys; as_dict = json.load(sys.stdin); print(as_dict)"')
I've got multiple of these commands calling external commands (not just python) and I have wrapped them with RunWithErrorHandling (adapted from https://github.com/hashivim/vim-terraform) so that I can get an error message instead of replacing the buffer content with the error.
I've been struggling with getting an error message displayed properly because multiline messages would have
\n replaced with
^@ instead of adding a line break when using
echo in combination with
echohl ErrorMsg displays everything the way I want, but the message is not available using
I ended up with the for loop and multiple calls to
echoerr as shown above, but it feels wrong and a multiline message is broken up into several "vim messages" so
:1messages shows me only the last line of a multiline message instead of the whole message.
It would be nice if I could echo the message so it's displayed the same way it is now and
:1messages shows me the whole message.
It seems like it should be possible because when I get an error running the following command:
command! DictToJson % python3 function_that_raises_an_exception()
I do get a nice stacktrace and
:1messages shows me the whole thing.