我试着阅读: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
。语法更加人性化 - 您可以使用
cgetexpr
对errorformat
进行实验。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
(丢弃head
和trail
)。
%+Chead %m trail
匹配^head .* trail$
,然后将整行附加到先前的%m
(包括head
和trail
)。
%+Gfoo
匹配以foo
开始的一行,并简单地将整行作为消息添加到qflist
中(即,仅具有message
字段的错误)。
此外,
%A
和%+A
之间,或者%E
和%+E
之间有什么区别?
%A
和%E
启动多行模式。%+
的意思似乎是"将正在解析的整行添加到message
,而不管%m
的位置如何"。
最后,
:help errorformat-multi-line
中Python的一个示例以以下字符结尾:%\@=%m
——%\@=
的含义是什么?
%\@=
转换为regexp限定符@=
,"将前面的原子与零宽度匹配"。