I tried reading :help errorformat
and googling (mostly stackoverflow), but can't understand some of the patterns mentioned there:
%s
- "specifies the text to search for to locate the error line. [...]"
- um, first of all, trying to understand the sentence at all, where do I put the "text to search", after the
%s
? before it? or, I don't know, does it maybe taint the whole pattern? WTF?
- secondly, what does this pattern actually do, how does it differ from regular text in a pattern, like some kinda
set efm+=,foobar
? the "foobar" here is for me also "text to search for"... :/
%+
- e.g. I I've seen something like that used in one question: %+C%.%#
- does it mean the whole line will be appended to a
%m
used in an earlier/later multiline pattern? if yes, then what if there was not %.%#
(== regexp .*
), but, let's say, %+Ccont.: %.%#
- would something like that work to capture only stuff after a cont.:
string into the %m
?
- also, what's the difference between
%C%.%#
and %+C%.%#
and %+G
?
- also, what's the difference between
%A
and %+A
, or %E
vs. %+E
?
- finally, an example for Python in
:help errorformat-multi-line
ends with the following characters: %\\@=%m
-- WTF does the %\\@=
mean?
I'd be very grateful for some help understanding this stuff.
Ah, errorformat
, the feature everybody loves to hate. :)
Some meta first.
- Some Vim commands (such as
:make
and :cgetexpr
) take the output of a compiler and parse it into a quickfix
list. errorformat
is a string that describes how this parsing is done. It's a list of patterns, each pattern being a sort of hybrid between a regexp and a scanf(3)
format. Some of these patterns match single lines in the compiler's output, others try to match multiple lines (%E
, %A
, %C
etc.), others keep various states (%D
, %X
), others change the way parsing proceeds (%>
), while yet others simply produce messages in the qflist
(%G
), or ignore lines in the input (%-G
). Not all combinations make sense, and it's quite likely you won't figure out all details until you look at Vim' sources. shrug
- You probably want to write
errorformat
s using let &erf='...'
rather than set erf=...
. The syntax is much more human-friendly.
- You can experiment with
errorformat
using cgetexpr
. cgetexpr
expects a list, which it interprets as the lines in the compiler's output. The result is a qflist
(or a syntax error).
qflist
s are lists of errors, each error being a Vim "dictionary". See :help getqflist()
for the (simplified) format.
- Errors can identify a place in a file, they can be simple messages (if essential data that identifies a place is missing), and they can be valid or invalid (the invalid ones are essentially the leftovers from parsing).
- You can display the current
qflist
with something like :echomsg string(getqflist())
, or you can see it in a nice window with :copen
(some important details are not shown in the window though). :cc
will take you to the place of the first error (assuming the first error in qflist
actually refers to an error in a file).
Now to answer your questions.
um, first of all, trying to understand the sentence at all, where do I put the "text to search", after the %s
? before it?
You don't. %s
reads a line from the compiler's output and translates it to pattern
in the qflist
. That's all it does. To see it at work, create a file efm.vim
with this content:
let &errorformat ='%f:%s:%m'
cgetexpr ['efm.vim:" bar:baz']
echomsg string(getqflist())
copen
cc
" bar baz
" bar
" foo bar
Then run :so%
, and try to understand what's going on. %f:%s:%m
looks for three fields: a filename, the %s
thing, and the message. The input line is efm.vim:" bar:baz
, which is parsed into filename efm.vim
(that is, current file), pattern ^\V" bar\$
, and message baz
. When you run :cc
Vim tries to find a line matching ^\V" bar\$
, and sends you there. That's the next-to-last line in the current file.
secondly, what does this pattern actually do, how does it differ from regular text in a pattern, like some kinda set efm+=,foobar
?
set efm+=foobar %m
will look for a line in the compiler's output starting with foobar
, then assign the rest of the line to the message
field in the corresponding error.
%s
reads a line from the compiler's output and translates it to a pattern
field in the corresponding error.
%+
- e.g. I I've seen something like that used in one question: %+C%.%#
does it mean the whole line will be appended to a %m
used in an earlier/later multiline pattern?
Yes, it appends the content of the line matched by %+C
to the message
produced by an earlier (not later) multiline pattern (%A
, %E
, %W
, or %I
).
if yes, then what if there was not %.%#
(== regexp .*
), but, let's say, %+Ccont.: %.%#
- would something like that work to capture only stuff after a cont.:
string into the %m
?
No. With %+Ccont.: %.%#
only the lines matching the regexp ^cont\.: .*$
are considered, the lines not matching it are ignored. Then the entire line is appended to the previous %m
, not just the part that follows cont.:
.
also, what's the difference between %C%.%#
and %+C%.%#
and %+G
?
%Chead %m trail
matches ^head .* trail$
, then appends only the middle part to the previous %m
(it discards head
and trail
).
%+Chead %m trail
matches ^head .* trail$
, then appends the entire line to the previous %m
(including head
and trail
).
%+Gfoo
matches a line starting with foo
and simply adds the entire line as a message in the qflist
(that is, an error that only has a message
field).
also, what's the difference between %A
and %+A
, or %E
vs. %+E
?
%A
and %E
start multiline patterns. %+
seems to mean "add the entire line being parsed to message
, regardless of the position of %m
".
finally, an example for Python in :help errorformat-multi-line
ends with the following characters: %\\@=%m
-- WTF does the %\\@=
mean?
%\\@=
translates to the regexp qualifier \@=
, "matches preceding atom with zero width".