Compilation mode的next-error如何跳过warning

不想一直开着VS占资源,时不时就占25%的CPU,所以想在emacs中通过msbuild编译sln文件,要调试再开VS。

想这样做的原因是,如果一直在emacs里面写代码而不经常编译,写完后编译可能会有一堆错误,如果经常切换vs编译,也很影响状态,所以能在emacs中编译最好。

好在摸索到办法了,设置compile-command为build.bat,bat文件中写编译命令:

@echo off
call "D:\software\VisualStudio2015\VC\bin\vcvars32.bat"
"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" "c:\work\projs\Cpp\Cpp.sln" /p:Configuration=Debug /p:Platform=x86 /m:2 

M-x compile 后下面是*compilation* buffer的输出:


    7>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\include\shlobj.h(1151): warning C4091: “typedef ”: 没有声明变量时忽略“tagGPFIDL_FLAGS”的左侧 [c:\work\proj\Cpp\Cpp\Cpp.vcxproj]
     7>c:\work\proj\cpp\dlib\Core/UIManager.h(56): warning C4091: “typedef ”: 没有声明变量时忽略“Dlib::EVENTTYPE_UI”的左侧 [c:\work\proj\Cpp\Cpp\Cpp.vcxproj]
     7>c:\work\proj\cpp\dlib\Core/UIManager.h(64): warning C4091: “typedef ”: 没有声明变量时忽略“Dlib::MSGTYPE_UI”的左侧 [c:\work\proj\Cpp\Cpp\Cpp.vcxproj]
     7>c:\work\proj\cpp\cpp\Bit.h : warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 [c:\work\proj\Cpp\Cpp\Cpp.vcxproj]
     7>c:\work\proj\cpp\cpp\Bit.h(644): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 [c:\work\proj\Cpp\Cpp\Cpp.vcxproj]
     7>main.cpp(36): error C2144: 语法错误:“void”的前面应有“;” [c:\work\proj\Cpp\Cpp\Cpp.vcxproj]
     7>main.cpp(36): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int [c:\work\proj\Cpp\Cpp\Cpp.vcxproj]
     7>已完成生成项目“c:\work\proj\Cpp\Cpp\Cpp.vcxproj”(默认目标)的操作 - 失败。
     6>已完成生成项目“c:\work\proj\Cpp\Cpp\Cpp.vcxproj.metaproj”(默认目标)的操作 - 失败。
     1>已完成生成项目“c:\work\proj\Cpp\Cpp.sln”(默认目标)的操作 - 失败。

这时M-x next-error 后会定位到 warning,由于有很多warning,我想直接定位到 error 而不是warning,

看了compilation-error-regexp-alist,正则太长有点头大,不知道怎么设置,当前值是:

compilation-error-regexp-alist is a variable defined in ‘compile.el’.
Its value is
(("^\\([0-9]+>\\)?\\(\\(?:[a-zA-Z]:\\)?[^:(	
]+\\)(\\([0-9]+\\)) : \\(?:fatal error\\|warnin\\(g\\)\\) C[0-9]+:" 2 3 nil
 (4))
 absoft ada aix ant bash borland python-tracebacks-and-caml cmake cmake-info comma cucumber msft edg-1 edg-2 epc ftnchek iar ibm irix java jikes-file maven jikes-line clang-include gcc-include ruby-Test::Unit gnu lcc makepp mips-1 mips-2 msft omake oracle perl php rxp sparc-pascal-file sparc-pascal-line sparc-pascal-example sun sun-ada watcom 4bsd gcov-file gcov-header gcov-nomark gcov-called-line gcov-never-called perl--Pod::Checker perl--Test perl--Test2 perl--Test::Harness weblint guile-file guile-line)
Original value was 
(absoft ada aix ant bash borland python-tracebacks-and-caml cmake cmake-info comma cucumber msft edg-1 edg-2 epc ftnchek iar ibm irix java jikes-file maven jikes-line clang-include gcc-include ruby-Test::Unit gnu lcc makepp mips-1 mips-2 msft omake oracle perl php rxp sparc-pascal-file sparc-pascal-line sparc-pascal-example sun sun-ada watcom 4bsd gcov-file gcov-header gcov-nomark gcov-called-line gcov-never-called perl--Pod::Checker perl--Test perl--Test2 perl--Test::Harness weblint guile-file guile-line)

为什么不用flycheck

build一次,等一年,CPU不花一分钱?

cpu花的是电费

手动编译花的是我的时间

我觉得时间比电费要贵一点吧

问题是flycheck不靠谱啊,我这能编译的工程也要报错:

Suspicious state from syntax checker c/c++-gcc: Flycheck checker c/c++-gcc returned non-zero exit code 1, but its output contained no errors: In file included from <stdin>:3:0:
LoginWindow.h:9:10: 鑷村懡閿欒 锛歎Ilib.h锛歂o such file or directory
 #include "UIlib.h"
          ^~~~~~~~~
缂栬瘧涓 柇銆 

Try installing a more recent version of c/c++-gcc, and please open a bug report if the issue persists in the latest release.  Thanks!

C-h v flycheck-gcc-include-path

你可以通过help buffer 里的 customize 往里添加 include 的路径

那乱码提示怎么修改

我 不 知道 啊

好吧,我再看看

需要做两件事,一个是设置正确的正则表达式识别msbuild/cl的error,warning和note,另一个是设置skip的阈值 来直接定位error。两者缺一不可。

Emacs相关参数

compilation-skip-threshold

Compilation motion commands skip less important messages. The value can be either:

  • 2 – skip anything less than error
    你需要设置成这个值。
  • 1 – skip anything less than warning
    这个是缺省值。
  • 0 – don’t skip any messages.

compilation-error-regexp-alist

之前照着手册对msvc的配置,能够识别msvc的error,warning和info, 因为实在是适应不了emacs的正则表达式语法,装了pcre2el包,还是pcre的语法符合人性

配置代码

(setq compilation-skip-threshold 2)     ; only navigate on errors
(add-to-list 'compilation-error-regexp-alist 'fixed-msvc)
(add-to-list 'compilation-error-regexp-alist-alist
             `(fixed-msvc
               ,(rxt-pcre-to-elisp (concat
                                    "^\\s*(?:\\d+>\\s*)?"  ; for msbuild, it will add "\d+>" on each line
                                    "("                    ; group 1: hyperlink
                                    "((?:\\w:)?[^:\t\n]+?)" ; group 2: file path
                                    "(?:\\((\\d+)\\))?"    ; group 3: line number
                                    "\\s*:\\s*"
                                    "(?:(note)|(warning)|(fatal )?error)(\\s+C\\d+)?" ; group 4: note, group 5: warning
                                    "\\s*:"
                                    ")"))
               2 3 nil (5 . 4) 1))

效果

厉害,设置compilation-skip-threshold为2果然可以了!

pcre2el的还没试,pcre的正则比自带的更容易理解么?

可以避免倾斜牙签综合征

但是我还不懂你们觉得正则就必须写成魔术字符串的想法

1 个赞

没有啊,只是不知道有rx这种更简单的办法

pcre的正则语法是主流,C++,python,ruby,[git/rip]grep里的正则表达式等等都是兼容这个的,学一次就能应付绝大部分情况。

EMACS的语法太过小众,包括rx(这个更是死死跟elisp绑在一起),如果已经对pcre的语法很熟,没必要把时间浪费在这上面。

因为EMACS不支持原始字符串,所以没办法只能多写一些 “\\”,如果使用C++/Python(支持原始字符串),写起来则要清爽多了。