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

9

我尝试阅读了:help errorformat并搜索了一些内容(大多数来自stackoverflow),但是无法理解其中提到的一些模式:

  • %s - "指定要搜索以查找错误行的文本。[...]"
    • 首先,我试图完全理解这个句子,在%s之后放置“要搜索的文本”?在它之前?或者,我不知道,它是否会污染整个模式?WTF?
    • 其次,这个模式实际上是做什么的?它与模式中的常规文本有何区别,例如set efm+=,foobar?这里的“foobar”对我来说也是“要搜索的文本”... :/
  • %+ - 例如,我在一个问题中看到过类似于%+C%.%#的用法I've seen something like that used in one question:
    • 它是否意味着整行将附加到早期/后续的多行模式中使用的%m?如果是,则如果没有%.%#(== regexp .*),而是像%+Ccont.:%.%#这样的东西 - 是否会起作用,以仅捕获cont.:字符串后面的内容到%m中?
    • %C%.%#%+C%.%#以及%+G之间有什么区别?
    • %A%+A%E%+E之间有什么区别?
  • 最后,在:help errorformat-multi-line中的Python示例以以下字符结尾:%\\@=%m - WTF是%\\@=的含义?

我将非常感谢您帮助我理解这些内容。

1个回答

23
啊,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(或语法错误)。 - qflist是错误列表,每个错误都是Vim“字典”。 有关格式(简化版)请参见:help getqflist()。 - 错误可以标识文件中的位置,它们可以是简单的消息(如果缺少可识别位置的基本数据),它们可以是有效的或无效的(无效的实际上是解析过程中剩下的部分)。 - 您可以像这样显示当前的qflist:echomsg string(getqflist()) ,也可以使用:copen在一个漂亮的窗口中查看它(但窗口中不显示一些重要细节)。 :cc将带您到第一个错误的位置(假设qflist中的第一个错误实际上指的是文件中的错误)。
现在回答您的问题。
引用:

嗯,首先,要理解句子,我在哪里放“要搜索的文本”,在%s之后? 在它之前?

您不需要这样做。 %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,它被解析为文件名 efm.vim(即当前文件)、模式 ^\V" bar\$ 和消息 baz。运行 :cc 时,Vim 尝试查找与 ^\V" bar\$ 匹配的行,并将光标移到那里。这是当前文件中倒数第二行。 set efm+=foobar %m 将查找编译器输出中以 foobar 开头的行,然后将行剩余部分分配给相应错误的 message 字段。 %s 从编译器输出中读取一行,并将其转换为相应错误的 pattern 字段。 %+C%.%#意味着将匹配到的行附加到先前(不是后来)多行模式(%A%E%W%I)产生的 message 中。 %+Ccont.:%.%# 不起作用,只有与正则表达式 ^cont\.: .*$ 匹配的行才被考虑,不匹配它的行将被忽略。然后将整行附加到前面的 %m,而不仅仅是跟随 cont.: 的部分。 %Chead %m trail 匹配 ^head .* trail$,然后仅将中间部分附加到以前的 %m(丢弃 headtrail)。 %+Chead %m trail 匹配 ^head .* trail$,然后将整个行附加到先前的 %m 中(包括 headtrail)。 %+Gfoo 匹配以 foo 开头的行,并将整行作为 qflist(即仅具有 message 字段的错误)中的消息添加。 %A%E 开始多行模式。 %+ 似乎意味着 "将正在解析的整行添加到 message 中,而不考虑 %m 的位置"。 %\\@= 转换为正则表达式限定符 \@=,表示"匹配前面的原子,但不消耗字符"。

1
哇,太棒了,现在我明白了 %s!就像标签文件中的内容一样,很好!关于 %+G,我现在感到惊讶,qflist 中只有消息字段?需要测试一下,有趣,谢谢!至于 %+A:help efm-ignore 明确列出了这种可能性:“例如 '%+A'”;你还确定这是语法错误吗?最后,关于 \@=,哎呀...你说这是神秘的正则表达式?谢谢,我没想到,也需要更多阅读。话虽如此,你能否分享一个链接以便完整吗?总之,非常感谢,完全接受回复!你太棒了 :) - akavel
看了一下源代码,你是对的:%+ 对于所有(带前缀的)格式都支持,并且其含义很简单:“将整行添加到 message 中,而不管 %m 如何”。虽然我想这对于 %A%E 等格式来说并不是很有用。:) 我会相应地编辑我的答案。 - lcd047

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接