2011-06-27 94 views
2

所以我有一個工具lints python的變化,我已經做出併產生錯誤和警告。我希望這可以在Emacs的編譯模式下使用,但我有一個問題。文件名在開始時只輸出一次,然後只顯示行號和錯誤和警告。下面是一個例子:Emacs的多行編譯模式正則表達式

Linting file.py 
E0602: 37: Undefined variable 'foo' 
C6003: 42: Unnecessary parens after 'print' keyword 
2 new errors, 2 total errors in file.py. 

它與pylint非常相似,但沒有output-format = parseable選項。我檢查的編譯錯誤,正則表達式,ALIST的文檔,並發現了一些有前途的:

If FILE, LINE or COLUMN are nil or that index didn't match, that
information is not present on the matched line. In that case the
file name is assumed to be the same as the previous one in the
buffer, line number defaults to 1 and column defaults to
beginning of line's indentation.

於是,我試着寫一個正則表達式,將可選匹配文件線,並拉出一組,然後休息會匹配其他線路。我認爲它會首先匹配

Linting file.py 
E0602: 37: Undefined variable 'foo' 

並罰款。然後它將繼續並匹配

C6003: 42: Unnecessary parens after 'print' keyword 

沒有文件。由於沒有文件,它應該使用前一個匹配的文件名嗎?這裏是我正在使用的正則表達式:

(add-to-list 'compilation-error-regexp-alist 'special-lint) 
(add-to-list 'compilation-error-regexp-alist-alist 
     '(special-lint 
      "\\(Linting \\(.*\\)\\n\\)?\\([[:upper:]][[:digit:]]+:\\s-+\\([[:digit:]]\\)+\\).*" 
      2 4 nil nil 3)) 

我已經用重新構建器檢查了它並手動在scratch buffer中進行了檢查。它的行爲如預期。第二組是文件名,第四組是行號,第三組是我想要突出顯示的。每當我嘗試,我得到的錯誤:

signal(error ("No match 2 in highlight (2 compilation-error-face)")) 

我有一種解決方法,涉及改造輸出編譯模塊看着它之前,但我更願意擺脫這一點,並有一個「純「的解決方案。我會很感激任何建議或指出我可能犯的任何愚蠢的錯誤。

編輯

下面托馬斯的僞代碼相當奏效。他提到做一個倒退重新搜索可能會弄亂比賽數據,而且確實如此。但是,通過在save-excursion之前添加save-match-data特殊形式解決了這個問題。

回答

3

FILE can also have the form (FILE FORMAT...), where the FORMATs (e.g. "%s.c") will be applied in turn to the recognized file name, until a file of that name is found. Or FILE can also be a function that returns (FILENAME) or (RELATIVE-FILENAME . DIRNAME). In the former case, FILENAME may be relative or absolute.

你可以嘗試寫一個正則表達式,它根本不匹配的文件名,只有列。然後爲該文件編寫一個向後搜索文件的函數。也許效率不高,但它應該具有可以向上移動通過錯誤消息的優點,並且當您跨越文件邊界時它仍然會識別正確的文件。

我沒有安裝嘗試了這一點必要的東西,而是採取以下僞代碼作爲一個靈感:

(add-to-list 'compilation-error-regexp-alist-alist 
     '(special-lint 
      "^\\S-+\\s-+\\([0-9]+\\):.*" ;; is .* necessary? 
      'special-lint-backward-search-filename 1)) 

(defun special-lint-backward-search-filename() 
    (save-excursion 
    (when (re-search-backward "^Linting \\(.*\\)$" (point-min) t) 
     (list (match-string 1))))) 

(這可能是因爲使用內部special-lint-backward-search-filename搜索功能會搞砸編譯錯誤 - 正則表達式的子組匹配,這將吸引。)

+0

我正在玩這個權利,它看起來很有希望。謝謝。我遇到了一些問題,可能是搜索搞亂了團體。當我找到某種方式時,我會讓你知道。 –

0

我不認爲你可以編譯你想做的事情,因爲它不會假設隨後的錯誤與以前看到的文件名有關。但是,這是另一種選擇。寫一個flymake插件。 Flymake始終在當前文件上運行,因此您只需告訴它如何查找行(以及可選列號)。

嘗試黑客行爲something like this,您可能會感到驚喜。

+0

儘管此工具不適用於單個文件。它與我的VCS集成,只處理我的更改。我確實有flymake的東西,我喜歡它,但是這個工具有一個我想用的不同的目的。 –