Vim quickfix整合编译工具的通用方法


  1. 背景
  2. quickfix工作原理
  3. 整合编译工具

背景

通常,我们在开发过程中,经常要写代码,编译,修改编译错误,这个过程会数十遍上百遍的重复。如果你是根据编译器输出的错误信息,打开出错的文件,找到出错的行,然后再开始修改,那效率未免太低下了。利用vim的quickfix模式,可以大大加快这一过程,你可以在vim启动编译,然后vim会根据编译器输出的错误信息,自动跳到第一个出错的地方,让你进行修改;修改完后,使用一个快捷键,跳到下一个错误处,再进行修改,方便的很。

但是在不同的公司往往有不同的构建工具,能否有一种通用的方法,整合这些工具到quickfix呢?答案是肯定的,当然完成的目的的前提是你足够了解quickfix的工作原理

quickfix工作原理

quickfix工作一般包括两个过程:
1、在使用”:make“时,vim会自动调用’makeprg’选项定义的命令进行编译(默认为make),并把编译输出重定向到一个临时文件中
2、当编译出现错误时,vim会根据’errorformat’选项定义的格式从上述临时文件中读出错误信息,根据这些信息形成quickfix列表,并跳转到第一个错误出现的地方。

然后你就可以轻松的使用以下命令逐个修复错误,然后再:make了

:cp   跳到上一个错误 ( :help :cp )      
:cn   跳到下一个错误 ( :help :cn )        
:cl   列出所有错误 ( :help :cl )

vim可以同时记住最新的10个错误列表,你还可以根据以下命令查看本次错误列表、以及前几次的错误列表,进行比较差错

:cl    列出所有错误 ( :help :cl )          
:cw    如果有错误列表,则打开quickfix窗口 ( :help :cw )          
:col   到前一个旧的错误列表 ( :help :col )         
:cnew  到后一个较新的错误列表 ( :help :cnew )

科普完毕,下面进入正题。

整合编译工具

下面以微信使用的构建工具blade为例,详细说明如果整合这些构建工具。整合的过程同样包括两部分:
1、定义makeprg选项的值为编译工具的编译命令,如:blade build -m32 -D -S
2、定义errorformat解析编译输出的错误信息,详细可以参考:help errorformat。如:

set errorformat+=%E%f:%l:%c:\ error:%m,%Z%m
set errorformat+=%-G%.%#
```                     
(含义:
1、解析以下内容的错误信息
2、忽略其他信息
)

One more thing,一般构建工具的使用的根路径,可能跟你工程的根路径有差异,这就导致quickfix跳转时找不到文件路径。例如,我的项目目录为dirA,归属于项目组dir下,编译工具从dir开始编译,输出的错误信息的文件名是相对项目组的路径:     

dir/dirA/file 11:22 error unfound varible a


解决的方式就是理解上面唯一加粗的正文"**并把编译输出重定向到一个临时文件中**",既然quickfix解析的只是输出过后的临时文件,那我们就可以按照自己的需要,在makeprg中首先处理得到的编译输出为想要的格式,再让quickifx解析。例如,将以上信息使用sed工具(sed 's/^dir/\/home\/cyningsun\/dir\/g')处理为绝对路径:        

/home/cyningsun/dir/dirA/file 11:22 error unfound varible a


无论你使用怎样的编译工具,通过自定义脚本的处理编译输出,你总能得到让quickfix正确识别的信息

### 最后
最后总结一下,并列出我的配置  

1、创建自己的脚本,并将脚本添加到自己的环境变量中:

```sh
mmake:
#! /bin/bash
blade build -m32 -D -S |s/^dir/\/home\/cyningsun\/dir\/g

2、配置makeprg

set makeprg=mmake

3、配置errorformat

set errorformat+=%E%f:%l:%c:\ error:%m,%Z%m
set errorformat+=%-G%.%#

然后,可以愉快的工作了~~~

本文作者 : cyningsun
本文地址https://www.cyningsun.com/06-13-2015/vim-quickfix.html
版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!