vimerrorformat

What's the meaning of some advanced patterns in vim errorformat? (%s, %+, %\\@=)


I tried reading :help errorformat and googling (mostly stackoverflow), but can't understand some of the patterns mentioned there:

I'd be very grateful for some help understanding this stuff.


Solution

  • Ah, errorformat, the feature everybody loves to hate. :)

    Some meta first.

    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".