vim errorformat 中一些高级模式的含义是什么? (%s, %+, %\\@=)

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

我尝试阅读 :help errorformat 和谷歌搜索(主要是 Whosebug),但无法理解那里提到的一些模式:

如果能帮助我理解这些内容,我将不胜感激。

啊,errorformat,人人又爱又恨的功能。 :)

首先是一些元数据。

  • 一些 Vim 命令(例如 :make:cgetexpr)获取编译器的输出并将其解析为 quickfix 列表。 errorformat 是一个字符串,描述了这个解析是如何完成的。它是一个模式列表,每个模式都是正则表达式和 scanf(3) 格式之间的一种混合。其中一些模式匹配编译器输出中的单行,其他模式尝试匹配多行(%E%A%C 等),其他模式保持各种状态(%D , %X), 其他人改变解析的方式 (%>), 而其他人只是在 qflist (%G) 中生成消息, 或者忽略输入中的行 ( %-G)。并非所有组合都有意义,而且很可能在查看 Vim' 来源之前您不会弄清楚所有细节。 耸肩
  • 您可能希望使用 let &erf='...' 而不是 set erf=... 来编写 errorformat。语法 更人性化。
  • 您可以使用 cgetexpr 来试验 errorformatcgetexpr 需要一个列表,它将其解释为编译器输出中的行。结果是 qflist(或语法错误)。
  • qflists 是错误列表,每个错误都是 Vim "dictionary"。有关(简化的)格式,请参阅 :help getqflist()
  • 错误可以标识文件中的一个位置,它们可以是简单的消息(如果缺少标识一个位置的基本数据),并且它们可以是有效的或无效的(无效的基本上是解析的遗留物)。
  • 你可以用:echomsg string(getqflist())之类的东西显示当前的qflist,或者你可以用:copen在漂亮的window中看到它(一些重要的细节没有显示虽然在 window 中)。 :cc 会将您带到第一个错误的位置(假设 qflist 中的第一个错误实际上是指文件中的错误)。

现在回答你的问题。

um, first of all, trying to understand the sentence at all, where do I put the "text to search", after the %s? before it?

你不知道。 %s 从编译器的输出中读取一行并将其转换为 qflist 中的 pattern。这就是它所做的一切。要在工作中查看它,请使用以下内容创建一个文件 efm.vim

let &errorformat ='%f:%s:%m'
cgetexpr ['efm.vim:" bar:baz']
echomsg string(getqflist())
copen
cc

" bar baz
" bar
" foo bar

然后 运行 :so%,并尝试了解发生了什么。 %f:%s:%m 查找三个字段:文件名、%s 内容和消息。输入行为efm.vim:" bar:baz,解析为filenameefm.vim(即当前文件),pattern^\V" bar$,messagebaz。当您 运行 :cc Vim 试图找到匹配 ^\V" bar$ 的行时,并将您发送到那里。这是当前文件中的倒数第二行。

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 将在编译器的输出中查找以 foobar 开头的行,然后将该行的其余部分分配给相应错误中的 message 字段。

%s 从编译器的输出中读取一行并将其转换为相应错误中的 pattern 字段。

%+ - 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?

是的,它将 %+C 匹配的行的内容附加到由较早(而不是较晚)的多行模式(%A%E 生成的 message , %W, 或 %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?

没有。使用 %+Ccont.: %.%# 时,仅考虑与正则表达式 ^cont\.: .*$ 匹配的行,不匹配的行将被忽略。然后整行追加到前面的%m,而不仅仅是cont.:.

后面的部分

also, what's the difference between %C%.%# and %+C%.%# and %+G?

%Chead %m trail 匹配 ^head .* trail$,然后仅将中间部分附加到前面的 %m(它丢弃 headtrail)。

%+Chead %m trail 匹配 ^head .* trail$,然后将整行附加到前面的 %m(包括 headtrail)。

%+Gfoo 匹配以 foo 开头的行,并简单地将整行作为消息添加到 qflist 中(即只有 message 字段)。

also, what's the difference between %A and %+A, or %E vs. %+E?

%A%E 开始多行模式。 %+的意思好像是"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?

%\@= 转换为正则表达式限定符 \@=、"matches preceding atom with zero width".