简体   繁体   English

Vim errorformat:在消息字符串中包含表达式的一部分

[英]Vim errorformat: include part of expression in message string

With vim's errorformat syntax, is there any way to use part of the message in filtering results? 使用vim的errorformat语法,有没有办法在过滤结果时使用部分消息?

As an example, some linker errors don't have anything explicit to distinguish them as an error on the line, other than the error itself: 例如,除了错误本身之外,一些链接器错误没有任何明确的区别将它们区分为行上的错误:

/path/to/foo.cpp:42: undefined reference to 'UnimplementedFunction'

or 要么

/path/to/foo.cpp:43: multiple definition of 'MultiplyDefinedFunction'

Using an errorformat of: 使用错误格式:

set efm=%f:%l:\ %m

would catch and display both of these correctly, but will falsely match many other cases (any line that starts with "[string]:[number]: "). 会正确地捕获并显示这两个,但会错误地匹配许多其他情况(任何以“[string]:[number]:”开头的行)。

Or, explicitly specifying them both: 或者,明确指定它们:

set efm=
set efm+=%f:%l:\ undefined\ reference\ to\ %m
set efm+=%f:%l:\ multiple\ definition\ of\ %m

removes the false positives, but the 'message' becomes far less useful -- the actual error is no longer included (just whatever is after it). 消除误报,但'消息'变得不那么有用 - 不再包含实际错误(只是在它之后的任何内容)。


Is there anything in the syntax I'm missing to deal with this situation? 我缺少什么语法来处理这种情况?

Ideally I'd like to be able to say something along the lines of: 理想情况下,我希望能够说出以下内容:

set efm+=%f:%l:\ %{StartMessage}undefined\ reference\ to\ %*\\S%{EndMessage}
set efm+=%f:%l:\ %{StartMessage}multiple\ definition\ of\ %*\\S%{EndMessage}

... where everything matched between StartMessage and EndMessage is used as the error's message. ...将StartMessage和EndMessage之间匹配的所有内容用作错误消息。

The errorformat can also use vim's regular expression syntax (albeit in a rather awkward way) which gives us a solution to the problem. errorformat也可以使用vim的正则表达式语法(虽然以相当笨拙的方式),它为我们提供了解决问题的方法。 We can use a non-capturing group and a zero-width assertion to require the presence of these signaling phrases without consuming them. 我们可以使用非捕获组和零宽度断言来要求存在这些信令短语而不消耗它们。 This then allows the %m to pick them up. 然后,这允许%m拾取它们。 As plain regular expression syntax this zero-width assertion looks like: 作为简单的正则表达式语法,这个零宽度断言看起来像:

\%(undefined reference\|multiple definition\)\@=

But in order to use it in efm we need to replace \\ by %\\ and % by %% and for use in a :set line we need to escape the backslashes, spaces and vertical bar so we finally have: 但是,为了使用它在efm我们需要替换\\%\\%%%和在使用:set行,我们需要逃避反斜杠,空间和竖杆上,我们终于有:

:set efm=%f:%l:\ %\\%%(undefined\ reference%\\\|multiple\ definitions%\\)%\\@=%m

With that the error file 有了那个错误文件

/path/to/foo.cpp:42: undefined reference to 'UnimplementedFunction'
/path/to/foo.cpp:43: multiple definition of 'MultiplyDefinedFunction'
notafile:123: just some other text

comes out as the following in :copen : 出现如下:copen

/path/to/foo.cpp|42| undefined reference to 'UnimplementedFunction'
/path/to/foo.cpp|43| multiple definition of 'MultiplyDefinedFunction'
|| notafile:123: just some other text

I've been using sed to rewrite the output in cases like this where I want to get some arbitrary output that's not nessicarily homogenous into the quickfix window. 我一直在使用sed在这样的情况下重写输出,我希望在quickfix窗口中获得一些不必要的任意输出。

You could write make.sh that fires off make (or whatever your're using to build) and trims off stuff you're not concerned with: 您可以编写make.sh来触发make(或者您正在构建的任何内容)并修剪掉您不关心的内容:

make | sed '/undefined reference\|multiple definition/!d'

(Deletes lines not containing 'undefined reference' or 'multiple definition') (删除不包含“未定义引用”或“多重定义”的行)

If that's going to get too unweildly because of the number of error strings you care about, you could do the inverse and just kill stuff you don't care about: 如果由于你关心的错误字符串的数量而变得太不合适,你可以做反过来,只是杀掉你不关心的东西:

make | sed 's/some garbage\|other useless message//'

then :set makeprg=make.sh in vim 然后:set makeprg=make.sh在vim中:set makeprg=make.sh

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM