2011-03-09 75 views
10

我正在爲PHPUnit編寫一個Vim編譯器插件。phpunit的Vim errorformat

我寫過以下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 

我很高興的報告文件和行是無論是在堆棧跟蹤的第一個或最後一個條目。最深的呼籲是問題的實際根源。跳到最高級別的通話意味着我可以用來進入通話堆棧。在上面的例子中,我更喜歡後者,SomeClassTest.php:15

回答

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

+0

謝謝Ilkka!這是一種享受。 – afternoon 2011-03-14 09:40:15

+1

我已經在Github上的一個插件中發佈了代碼: https://github.com/afternoon/vim-phpunit – afternoon 2011-03-14 09:48:39

+0

再看一遍,也許它沒有工作的原因是'%+ C%$ ''會在'%Z%$'之前始終匹配,因此多行消息從來沒有被正確地關閉。 – Ilkka 2011-03-14 10:32:00