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



我试着阅读:help errorformat和谷歌搜索(主要是stackoverflow),但无法理解其中提到的一些模式:

  • %s-"指定要搜索的文本以定位错误行。[…]">
    • 嗯,首先,试着理解这个句子,在%s之后,我应该把"要搜索的文字"放在哪里?之前?或者,我不知道,它可能会污染整个模式吗?WTF
    • 其次,这个模式实际上是做什么的,它与模式中的常规文本有什么不同,比如某种set efm+=,foobar?这里的"foobar"对我来说也是"要搜索的文本"…:/
  • %+-例如,我在一个问题中看到过类似的内容:%+C%.%#
    • 这是否意味着整行将被附加到早期/后期多行模式中使用的%m?如果是,那么如果没有%.%#(==regexp.*),而是%+Ccont.: %.%#-这样的东西只捕获cont.:字符串之后的东西到%m中吗
    • %C%.%#%+C%.%#%+G之间有什么区别
    • 另外,%A%+A,或者%E%+E之间有什么区别
  • 最后,:help errorformat-multi-line中Python的一个示例以以下字符结尾:%\@=%m-WTF是%\@=的意思吗

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

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

一些元优先。

  • 一些Vim命令(如:make:cgetexpr)获取编译器的输出,并将其解析为quickfix列表。errorformat是一个字符串,用于描述如何进行解析。这是一个模式列表,每个模式都是regexp和scanf(3)格式的混合。其中一些模式匹配编译器输出中的单行,另一些模式尝试匹配多行(%E%A%C等),另一些则保持各种状态(%D%X),其他模式更改解析进行的方式(%>),而另一些则只是在qflist中生成消息(%G),或忽略输入中的行(%-G)。并不是所有的组合都有意义,而且很可能在查看Vim的来源之前,你不会弄清楚所有的细节耸耸肩
  • 您可能希望使用let &erf='...'而不是set erf=...来编写errorformat。语法更加人性化
  • 您可以使用cgetexprerrorformat进行实验。cgetexpr需要一个列表,它将该列表解释为编译器输出中的行。结果是qflist(或语法错误)
  • qflist是错误列表,每个错误都是一个Vim"字典"。(简化)格式见:help getqflist()
  • 错误可以识别文件中的某个位置,可以是简单的消息(如果识别某个位置的基本数据丢失),也可以是有效的或无效的(无效的基本上是解析的剩余部分)
  • 您可以用类似:echomsg string(getqflist())的东西显示当前的qflist,也可以用: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)有何不同?

set efm+=foobar %m将在编译器的输出中查找以foobar开头的一行,然后将该行的其余部分分配给相应错误中的message字段。

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

%+-例如,我在一个问题中看到过类似的内容:%+C%.%#这是否意味着整条线将被附加到早期/后期多行图案中使用的%m

是的,它将由%+C匹配的行的内容附加到由较早(而不是较晚)的多行模式(%A%E%W%I)生成的message

如果是,那么如果没有%.%#(==regexp.*),而是%+Ccont.: %.%#-这样的东西只捕获cont.:字符串之后的东西到%m中吗?

否。对于%+Ccont.: %.%#,只考虑与正则表达式^cont.: .*$匹配的行,忽略与之不匹配的行。然后,整行被附加到先前的%m,而不仅仅是cont.:之后的部分。

此外,%C%.%#%+C%.%#%+G之间有什么区别?

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

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

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

此外,%A%+A之间,或者%E%+E之间有什么区别?

%A%E启动多行模式。%+的意思似乎是"将正在解析的整行添加到message,而不管%m的位置如何"。

最后,:help errorformat-multi-line中Python的一个示例以以下字符结尾:%\@=%m——%\@=的含义是什么?

%\@=转换为regexp限定符@=,"将前面的原子与零宽度匹配"。

最新更新