4

I am trying to set errorformat=... so that I can parse errors like the following:

error: cannot format /home/user/repo/src/file1.py: Cannot parse: 2:5: some source code here
error: cannot format /home/user/repo/src/file2.py: Cannot parse: 7:10: some_more source code here
Oh no! ๐Ÿ’ฅ ๐Ÿ’” ๐Ÿ’ฅ
2 files failed to reformat.

(For context, this error is produced by the python black code formatter. I am writing CompilerSet makeprg=black and CompilerSet errorformat=... in the file ~/.vim/compiler/black.vim, for use with the vim-dispatch plugin).

My question is about how to set errorformat so that the output in the quickfix window contains all the relevant pieces of information. Ideally, all of the following should be printed in the quickfix window:

  • cannot format
  • Cannot parse
  • source code...

I've had some success with setting

errorformat=error:\ cannot\ format\ %f:\ %s:\ %l:%c:\ %m

which results in the following quickfix output:

file1.py|2 col 5| some source code here
file2.py|7 col 10| some_more source code here
|| Oh no! ๐Ÿ’ฅ ๐Ÿ’” ๐Ÿ’ฅ
|| 2 files failed to reformat.

I have also tried

errorformat=error:\ cannot\ format\ %f:\ %m:\ %l:%c:\ %s

which results in

file2.py|7 col 10| Cannot parse
file1.py|2 col 5| Cannot parse
|| Oh no! ๐Ÿ’ฅ ๐Ÿ’” ๐Ÿ’ฅ
|| 2 files failed to reformat.

Ideally, the quickfix output should look something like this:

file2.py|7 col 10| cannot format: Cannot parse: some source code here
file1.py|2 col 5| cannot format: Cannot parse: some_more source code here
|| Oh no! ๐Ÿ’ฅ ๐Ÿ’” ๐Ÿ’ฅ
|| 2 files failed to reformat.

Printing this additional information would be useful to me in quickly debugging the problem(s) in the quickfix list.

I've tried variations on using multiple %m and %s symbols; all of the following give errors:

  • error:\ cannot\ format\ %f:\ %m:\ %l:%c:\ %m
  • error:\ cannot\ format\ %f:\ %s:\ %l:%c:\ %s
  • error:\ %m\ %f:\ %m:\ %l:%c:\ %m

Any ideas?

1
  • In a tangentially-related issue, I'm having trouble using :cnext with the above. Vim jumps to the correct file but not to the correct line-number. Not sure if it's related to the errorformat...
    – Jasha
    Jun 19 '20 at 23:48
3

The issue is that the text you want to see in the message field of the quickfix list is disconnected in the original output:

error: cannot format /home/user/repo/src/file1.py: Cannot parse: 2:5: some source code here
       ^^^^^^^^^^^^^                               ^^^^^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^

Try to filter the errors first, with some script, to format the output so that all these parts are connected:

# before
error: cannot format /home/user/repo/src/file1.py: Cannot parse: 2:5: some source code here
       ^^^^^^^^^^^^^                               ^^^^^^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^

# after
/home/user/repo/src/file1.py:2:5:cannot format: Cannot parse: some source code here
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It's easier to write an errorformat for the latter output; %f:%l:%c:%m should work.

See :h errorformat-javac for an example.


Here's one possible implementation.

Write this short sed script in ~/bin/vim-black-filter:

#!/bin/sed -f

s/error: \(cannot format\) \(.*:\) \(Cannot parse: \)\([0-9]\+:[0-9]\+:\) \(.*\)/\2\4\1: \3\5/

Make the script executable, and make sure ~/bin is in your path:

$ chmod +x ~/bin/vim-black-filter

Then, in your compiler plugin ~/.vim/compiler/black.vim, write this:

let current_compiler = 'black'

if exists(':CompilerSet') != 2
    com -nargs=* CompilerSet setl <args>
endif

CompilerSet mp=black\ 2>&1\ \\\|\ vim-black-filter
CompilerSet efm=%f:%l:%c:%m

In a tangentially-related issue, I'm having trouble using :cnext with the above. Vim jumps to the correct file but not to the correct line-number. Not sure if it's related to the errorformat...

It's probably because you used %s in your errorformat.

Whatever text is matched by %s, it's used to populate the pattern field of a quickfix list entry. In turn, this field is used to locate the error line. And the pattern field has priority over the lnum one.

1
  • 1
    Thank you for the detailed answer. I hadn't thought to try preprocessing black's output before passing it to vim.
    – Jasha
    Jun 20 '20 at 20:58

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.