If 'errorformat' uses multi-line messages (%A, %C, %Z) and output is added
line-by-line with :caddexpr, vim omits lines and adds duplicate lines to the
quickfix. It's unsurprising that vim is unable to parse the multiple lines when
it only receives the first one, but I wouldn't expect it to repeat output. I'd
also hope it wouldn't drop output.
c:/scratch/test.vim
function! Test_multiline_efm() let output = [ \ '[python3 -t scratch\mytest.py]' \ , 'hello' \ , 'Traceback (most recent call last):' \ , ' File "scratch\mytest.py", line 2, in <module>' \ , ' raise Exception("bad")' \ , 'Exception: bad' \ , '[Finished in 0 seconds with code 1]' \ , 'placeholder 1' \ , 'placeholder 2' \ , 'placeholder 3' \ , 'placeholder 4' \ , 'placeholder 5' \] " Multi-line (%A, %Z) causes duplicated and missing lines. let &efm = '%A%\s%#File "%f"\, line %l%.%#,%Z %m' " Same with set: set errorformat=%A%\\s%#File\ \"%f\"\\,\ line\ %l\\,%.%#,%Z\ \ \ \ %m " Single-line is fine, but obviously can't match error message to line since " they're on separate lines. "~ let &efm = '%\s%#File "%f"\, line %l\,%.%#, %m' call setqflist([]) " Add output all at once -- works wonderfully: " || [python3 -t scratch\mytest.py] " || hello " || Traceback (most recent call last): " scratch/mytest.py|2| raise Exception("bad") " || Exception: bad " || [Finished in 0 seconds with code 1] " || placeholder 1 " || placeholder 2 " || placeholder 3 " || placeholder 4 " || placeholder 5 "~ caddexpr output " Add output one at a time -- omits and duplicates lines: " || [python3 -t scratch\mytest.py] " || hello " || Traceback (most recent call last): " scratch/mytest.py|2| raise Exception("bad") " || [python3 -t scratch\mytest.py] " || hello " || Traceback (most recent call last): " scratch/mytest.py|2| " || placeholder 3 " || placeholder 4 " || placeholder 5 for line in output caddexpr line " Not sure if this should work better, but I can't figure out how to " make it work. "~ call setqflist([{'text' : line}], 'a', {'efm' : &efm}) endfor endf copen call Test_multiline_efm()
> gvim --clean +"source c:/scratch/test.vim"
I would expect the output to not duplicate lines and to include the omitted lines:
|| [python3 -t scratch\mytest.py]
|| hello
|| Traceback (most recent call last):
scratch/mytest.py|2|
|| raise Exception("bad")
|| Exception: bad
|| [Finished in 0 seconds with code 1]
|| placeholder 1
|| placeholder 2
|| placeholder 3
|| placeholder 4
|| placeholder 5
Instead, it omits 4 lines that appear after the %Z-matching line. If I insert another
placeholder line before 'raise Exception' (so there's a non-matching line
between %A and %Z), then it outputs as desired. So it seems like matching %A
and then matching %Z on the next input triggers this bad behaviour.
I'm using skywind3000/asyncrun.vim which adds uses vim jobs to run commands in
the background and add their output to the quickfix as it's received. It uses
caddexpr to add the lines.
I have a python compiler script that uses multi-line output to capture the
traceback and add it to the quickfix.
Using the two of these in combination causes the quickfix to be populated with
duplicate lines and some lines are missing.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.![]()
If you close and then reopen the quickfix window it will show the correct output. It looks like it's parsed correctly but just not properly displayed in the quickfix window (at first).
Regarding setqflist():
" Line by line for line in output call setqflist([], 'a', {'lines': [line], 'efm' : &efm}) endfor " Or all lines at once call setqflist([], 'a', {'lines': output, 'efm' : &errorformat})
Both give the same result. You can check the current quickfix list with getqflist():
[
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "[python3 -t scratch\\mytest.py]"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "hello"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "Traceback (most recent call last):"
},
{
"lnum": 2,
"bufnr": 4,
"col": 0,
"pattern": "",
"valid": 1,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "\nraise Exception(\"bad\")"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "Exception: bad"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "[Finished in 0 seconds with code 1]"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "placeholder 1"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "placeholder 2"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "placeholder 3"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "placeholder 4"
},
{
"lnum": 0,
"bufnr": 0,
"col": 0,
"pattern": "",
"valid": 0,
"vcol": 0,
"nr": -1,
"type": "",
"module": "",
"text": "placeholder 5"
}
]If you close and then reopen the quickfix window
Looks like you don't even need to close the quickfix. Looks like :copen fixes it regardless!
Thanks for clearing up setqflist. Does that mean that if I want to pass {what}, I should always pass an empty list for {list}?
Maybe that's implied by this line from :help setqflist:
When {what} is not present, use the items in {list}.
Although it wasn't clear to me that this line no longer applies:
If you supply an empty {list}, the quickfix list will be cleared.
If you close and then reopen the quickfix window
Looks like you don't even need to close the quickfix. Looks like
:copenfixes it regardless!
Thanks for clearing up setqflist. Does that mean that if I want to pass
{what}, I should always pass an empty list for{list}?
Maybe that's implied by this line from
:help setqflist:When {what} is not present, use the items in {list}.
Although it wasn't clear to me that this line no longer applies:
If you supply an empty {list}, the quickfix list will be cleared.
Sorry for the delay. Confirmed fixed for me. Thanks!
—
You are receiving this because you commented.