所以我有一个工具lints python我做的更改并产生错误和警告。我希望这可以在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选项。我查看了compilation-error-regexp-alist的文档,发现了一些有希望的东西:
如果FILE,LINE或COLUMN为零或索引不匹配,则为< 匹配的行上不存在信息。在那种情况下 假定文件名与中的前一个相同 缓冲区,行号默认为1,列默认为
线的缩进开始。
所以我尝试编写一个正则表达式,它可以选择匹配文件行并将其拉出一个组,然后其余的将与其他行匹配。我以为它会先匹配
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))
我已经通过重新构建并在临时缓冲区中手动检查了它。它的行为与预期一致。第二组是文件名,第四组是行号,第三组是我想要突出显示的。每当我尝试这个时,我都会收到错误:
signal(error ("No match 2 in highlight (2 compilation-error-face)"))
我有一个解决方法,涉及在编译模块查看之前转换输出,但我更愿意摆脱它并拥有一个“纯粹”的解决方案。我会很感激任何建议或指出我可能犯过的任何愚蠢错误。
修改
下面托马斯的伪代码效果很好。他提到做一个向后重新搜索可能会弄乱匹配数据,而且确实如此。但是,通过在save-match-data
之前添加save-excursion
特殊表单来解决这个问题。
答案 0 :(得分:3)
FILE也可以有表格(FILE FORMAT ...),其中FORMAT(例如 “%s.c”)将依次应用于 识别文件名,直到文件为 找到那个名字。或文件也可以 是一个返回的函数(FILENAME) 或(RELATIVE-FILENAME.DIRNAME)。在 前一种情况,FILENAME可能是 相对的或绝对的。
您可以尝试编写与文件名完全匹配的正则表达式,只编写列。然后,对于该文件,编写一个向后搜索该文件的函数。可能效率不高,但它应该具有以下优势:您可以向上移动错误消息,并且当您跨越文件边界时它仍然会识别正确的文件。
我没有安装必要的东西来试试这个,但是请使用以下伪代码作为灵感:
(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
中使用搜索功能会搞砸compilation-error-regexp的子组匹配,这会很糟糕。)
答案 1 :(得分:0)
我认为你不能在这里做你想要的编译,因为它不会假设后续错误与先前看到的文件名有关。但这是另一种选择;写一个flymake
插件。 Flymake始终在当前文件上运行,因此您只需要告诉它如何查找行(以及可选的列)数字。
尝试入侵something like this,您可能会感到惊喜。