啊,
errorformat
,每个人都爱恨交加的功能。 :)
先说一些元信息:
- 一些Vim命令(例如
:make
和
:cgetexpr
)接受编译器的输出并将其解析为一个
quickfix
列表。
errorformat
是一个描述如何进行此解析的字符串。 它是一个模式列表,每个模式是一种介于正则表达式和
scanf(3)
格式之间的混合体。 这些模式中的一些匹配编译器输出中的单行,其他模式尝试匹配多行(
%E
,
%A
,
%C
等),其他保留各种状态(
%D
,
%X
),其他更改解析过程的方式(
%>
),而其他只是在
qflist
中生成消息(
%G
)或忽略输入中的行(
%-G
)。 并非所有组合都有意义,您很可能不会了解所有细节,直到查看Vim的源代码为止。
耸肩
- 您可能希望使用
let &erf ='...'
而不是
set erf = ...
来编写
errorformat
。 语法更为友好。
- 您可以使用
cgetexpr
尝试
errorformat
。
cgetexpr
期望一个列表,将其解释为编译器输出中的行。 结果是
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
(丢弃
head
和
trail
)。
%+Chead %m trail
匹配
^head .* trail$
,然后将整个行附加到先前的
%m
中(包括
head
和
trail
)。
%+Gfoo
匹配以
foo
开头的行,并将整行作为
qflist
(即仅具有
message
字段的错误)中的消息添加。
%A
和
%E
开始多行模式。
%+
似乎意味着 "将正在解析的整行添加到
message
中,而不考虑
%m
的位置"。
%\\@=
转换为正则表达式限定符
\@=
,表示"匹配前面的原子,但不消耗字符"。
%s
!就像标签文件中的内容一样,很好!关于%+G
,我现在感到惊讶,qflist 中只有消息字段?需要测试一下,有趣,谢谢!至于%+A
::help efm-ignore
明确列出了这种可能性:“例如 '%+A'”;你还确定这是语法错误吗?最后,关于\@=
,哎呀...你说这是神秘的正则表达式?谢谢,我没想到,也需要更多阅读。话虽如此,你能否分享一个链接以便完整吗?总之,非常感谢,完全接受回复!你太棒了 :) - akavel%+
对于所有(带前缀的)格式都支持,并且其含义很简单:“将整行添加到message
中,而不管%m
如何”。虽然我想这对于%A
和%E
等格式来说并不是很有用。:) 我会相应地编辑我的答案。 - lcd047