我正在为
PHPUnit开发一个Vim编译器插件.
我写了以下的错误格式.错误消息被正确提取,但文件和行号不是.
CompilerSet errorformat=%E%n)\ %.%#,\%C%m,\%+C%$,\%C%f:%l,\%Z%$
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
我很高兴报告的文件和行是堆栈跟踪中的第一个或最后一个条目.最深刻的呼吁是问题的实际来源.跳到顶级调用意味着我可以使用下来进入调用堆栈.我更喜欢后者,SomeClassTest.PHP:15在上面的例子中.
我认为问题是%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()之后的打印行.