Vim针对PHPUnit的错误格式设置

10
我正在为PHPUnit编写 Vim 编译器插件。
我已经编写了下面的错误格式代码。errorformat 已经成功提取了错误信息,但是文件和行号没有被正确提取。
CompilerSet errorformat=%E%n)\ %.%#,
                       \%C%m,
                       \%+C%$,
                       \%C%f:%l,
                       \%Z%$

PHPUnit的输出大致是这样的:

PHPUnit 3.5.12 by Sebastian Bergmann.

...............................................................  63 / 134 ( 47%)
.........................E.....

Time: 0 seconds, Memory: 11.25Mb

There was 1 error:

1) SomeClassTest::testSomething
Undefined property: SomeClass::$var

/path/to/SomeClass.php:99
/path/to/SomeClassTest.php:15

FAILURES!
Tests: 94, Assertions: 170, Errors: 1.

Press ENTER or type command to continue

我希望报告的文件和行号可以是堆栈跟踪中的第一项或最后一项。最深层的调用是问题实际发生的源头。跳转到顶级调用意味着我可以使用 to step down into the call stack 逐级跟踪调用堆栈。在上面的例子中,我更倾向于选择后者,即 SomeClassTest.php:15

1个回答

5

我认为问题出在%Z规则的措辞上。一开始我想到的是:

:set errorformat=%E%n)\ %.%#,%Z%f:%l,%C%m,%-G%.%#

这将捕获第一个文件名并将其与错误消息关联。

由于某种原因,关联最后提到的文件名要困难得多。我无法使用efm来完成它,而是通过编写这个Python过滤器进行了一些修改:

import sys                                                                  
import re
errors = []
OTHER = 0
MESSAGE = 1
FILE_LINE = 2
next_is = OTHER
lines = sys.stdin.readlines()
for line in lines:
    line = line.strip()
    if (next_is == OTHER):
        if (re.search("^[0-9]+\)", line)):
            next_is = MESSAGE
    elif (next_is == MESSAGE):
        errors.append([line, ''])
        next_is = FILE_LINE
    elif (next_is == FILE_LINE):
        if (re.search("^.+:[0-9]+", line)):
            errors[-1][1] = line
        elif (len(line) == 0 and len(errors[-1][1]) > 0):
            next_is = OTHER

for error in errors:
    print "{0}:{1}".format(error[1], error[0])

这将捕获所有错误并以单行格式输出它们。相关的文件名和行号是错误的最后提到的。这个脚本覆盖了所有其他输出,但通过在line = line.strip()之后添加例如print line即可解决。


1
我已经将代码发布在Github上的一个插件中:https://github.com/afternoon/vim-phpunit - afternoon
再看一遍,也许它没有起作用的原因是 %+C%$ 总是会在 %Z%$ 之前匹配,因此多行消息从未被正确“关闭”。 - Ilkka
嗯,看起来这与上一个函数调用匹配(列表中的第一个,SomeClass.php:99)。当常见测试函数被多个测试调用时,这使得诊断问题变得困难。使用第一个函数调用(列表中的最后一个 - SomeClassTest.php:15)会更有用,因为C-]允许您进入没有运行时堆栈信息的调用。 - afternoon
应该使用 %Q 而不是 %G,呵呵。 - Ilkka
似乎这些旨在捕获一个文件名,然后应用于多个错误,而不是捕获单个错误的多个文件名。但是,如果它们可以被滥用为此目的,那就太好了 :-). - afternoon
显示剩余2条评论

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