您的位置:首页 > 编程语言

自己动手定制一个高效阅读源代码的vim

2013-01-17 20:20 148 查看
自己动手定制一个高效阅读源代码的vim

阅读大型工程的源代码时,我们经常需要在多个源文件之间实现函数、宏定义、外部变量等的跳转查询,但这些功能仅靠vim完成是困难的,所以还需借助一些额外的工具来打造一款合适自己的vim。

1、安装VIM

安装vim比较简单,也没有特别要注意的地方,这里就不多讲。如果你是在ubuntu系统下,直接采用:

$ sudo apt-get install vim或者$
sudo apt-get install vim-gnome。安装好之后,试编辑一个文件,看看是否运行正常(一般不会有问题)。然后看看自己的用户目录下有没有一个vim隐藏配置文件:.vimrc和一个vim隐藏文件:.vim。如果没有,可以通过下面方式创建:

1) 打开vim,在命令行模式下输入::!cp
-i $VIMRUNTIME/vimrc_example.vim ~/.vimrc

就会在自己的用户目录下生成vim隐藏配置文件:.vimrc。

2) cd到用户目录下,运行下面命令:

$ mkdir -p /.vim/{plugin,doc,syntax}

就会产生三个目录:~/.vim/plugin、~/.vim/doc、~/.vim/syntax

2、ctag的配置

tags文件是实现跳转功能的数据库文件,就是它把我们送到我们想要去的地方的。比如我们在程序里调用一个函数i2c_master_recv,在某个时刻想查看这函数本身是怎么实现的。那只需把光标停在关键词上,再按一下组合键:“ctrl+]”, 就会立刻跳转到库函数i2c_master_recv的源代码的地方,再按一下组合键 “ctrl+o” 就可以跳回来。

当然如果你要查询的函数是对一个系统调用的封装,你就可以顺着tags 提供的道路跳到内核去查看源代码是怎么写的,当然这时候可能会有不止简单的两层封装定义,但我们一次次跳转就可以深入其里,了解内幕。

首先,我们要安装ctags工具:

$ sudo apt-get install ctags

如果提示找不到软件包ctags,就update一下你的软件源,还不行的话试试把ctags改成 exuberant-ctags。下载完后,你就可以用它来产生标签文件tags了。

ctags常用命令列举:

1) 建立数据库命令

# ctags -R或者exuberant-ctags
-R // 这个命令是在终端命令行下执行的(-R表示递归向下)

2) 在vim编辑器中浏览

:ta x

跳转到符号x的定义处,如果有多个符号,直接跳转到第一处

:ts x

列出符号x的定义

:tj x

可看做上面两个命令的合并,如果只找到一个符号定义,那么直接跳转到符号定义处,如果有多个,则让用户自行选择。

Ctrl+]

跳转到当前光标下符号的定义处,和ta类似。

Ctrl+t

跳转到上一个符号定义处,和上面的配合基本上就能自由跳转了。

:tn和:tp

是在符号的多个定义之间跳转。

Ctags使用举例:

1) 在跳转目的地执行这条命令

# ctags -R

假设正在编辑/kernel/drivers/input\touchscreen/tcc_ts_cypress.c,这个文件可能会调用内核中的某个函数,我们想直接跳转到内核去查看改函数的具体实现,应该怎么办呢?我们现在就应该在/kernel下执行上面那条命令:

# cd kernel

# ctags -R

命令中的选项-R的意思是:递归地进入当前目录下的所有子目录,把在该目录下的所有文件的关键词(包括函数名、宏、文件名等等关联到一起,并且写入一个tags文件)。

2) 在$HOME/.vimrc文件中,添加一条指令,指明当前编辑程序的所在地。

在$HOME/.vimrc文件最后添加如下内容:

au BufEnter /home/zhangxiaoqi/eclair_101206/* setlocal tags+=/home/zhangxiaoqi/eclair_101206/tags

上面蓝色标记的路径要更行成你自己的路径。其中/home/zhangxiaoqi/eclair_101206/*的意思是:在该路径下的所有文件都可以通过tags文件实现跳转;这个tags数据库文件,就是刚才用ctags
-R命令生成的,正是由路径/home/zhangxiaoqi/eclair_101206/tags指定。

3、使用VIM插件TagList(源代码结构浏览)

Taglist是vim的一个插件,可以方便地在终端侧边显示出当前程序所有的函数、宏等信息,支持鼠标双击跳转,对于规模比较大的代码而言,这是一个非常实用功能。

下载链接:http://download.csdn.net/source/249784

下载完解压,得到两个文件夹 doc和plugin,将两个文件夹存放到用户目录下的隐藏文件夹.vim下(还记得.vim这个路径吧)。然后,用vim打开程序源码,敲下命令:Tlist 打开列表,再输入一次关闭列表。

4、使用文件浏览器和窗口管理器WinManager

在使用vim的过程中,你也许会碰到这样的情况:你本来想打开一个文件,但是错误的用vim打开了一个路径,这时候,居然没有返回错误信息,而是给出一个这个路径下的文件列表。这一功能实际上是由vim的文件浏览器插件netrw实现的。我们如何把这一功能应用到平时阅读海量源代码的过程中呢?如何将TagList窗口和netrw窗口整合起来呢?这时候,WinManager插件就派上用场了。

下载链接:http://www.vim.org/scripts/script.php?script_id=95

在 ~/.vim 目录下解压 winmanager.zip,然后在~/.vimrc中增加下面两句:

let g:winManagerWindowLayout='FileExplorer|TagList'

nmap wm :WMToggle<cr>

在vim的normal状态下输入"wm",即可发现很奇妙的分割串口画面。

5、配置cscope

先安装吧,$
sudo apt-get install cscope。

然后在~/.vimrc中增加一句:

:set cscopequickfix=s-,c-,d-,i-,t-,e-

这步操作的目的是设定是否使用 quickfix 窗口来显示 cscope 的查询结果。

跟Ctags类似,要使用其功能必须先为你的代码生成一个cscope的数据库,在项目的根目录运行下面的命令:

$ cscope -Rbq

会生成三个文件:

-rw-rw-r-- 1 wooin wooin 1.1M 2007-09-30 10:56 cscope.in.out

-rw-rw-r-- 1 wooin wooin 6.7M 2007-09-30 10:56 cscope.out

-rw-rw-r-- 1 wooin wooin 5.1M 2007-09-30 10:56 cscope.po.out

这时候,你可以把下面这条命令写进~/.vimrc文件里面,以保证每次打开vim都会加载cscope数据库文件:

cs add /home/zhangxiaoqi/eclair_101206/cscope.out /home/zhangxiaoqi/eclair_101206/

上面这条指令的意思是让/home/zhangxiaoqi/eclair_101206/路径下的所有文件都有权访问/home/zhangxiaoqi/eclair_101206/cscope.out数据库文件。这一步操作是和ctag类似的(你可以回去看看ctags的配置)。

这时,你可以打开某一个源程序文件, 开始编辑。下面来做一个具体的操作, 查找函数good()的定义, 用命令:

:cs find g good

如果自动跳转的位置你不满意, 想看其他的结果, 可以用下面的命令打开QuickFix窗口:

:cw # 还记得之前对quickfix窗口的配置吧

6、QuickFix窗口

可以人为地在程序源文件造成几处小小的容易辨认的错误,然后用下面的命令进行编译:

:make

显然编译会报很多错误,当编译结束并退出到源码界面时,刚才编译器报的错误都已经看不到了,但是我们可以用QuickFix窗口再将错误信息找出来。用下面的命令调出QuickFix窗口:

:cw

此时你就可以看如下图所示的QuickFix窗口了。

7、使用插件MiniBufExplorer快速浏览和操作多个打开的文件

下载地址 http://www.vim.org/scripts/script.php?script_id=159

将minibufexpl.vim文件拷贝到 ~/.vim/plugin 文件夹中。

重新启动vim, 当你只编辑一个文件的时候MiniBufExplorer派不上用场,当你打开第二个文件的时候,
MiniBufExplorer窗口就自动弹出来了。

如果在~/.vimrc中设置了下面这句:

let g:miniBufExplMapWindowNavVim = 1

则可以用<C-h,j,k,l>切换到上下左右的窗口中去,就像:

C-w,h j k l 向"左,下,上,右"切换窗口。

8、使用插件a.vim在.c文件和.h文件之间相互切换

安装好a.vim后有下面的几个命令可以用了:

:A 在新Buffer中切换到c\h文件

:AS 横向分割窗口并打开c\h文件

:AV 纵向分割窗口并打开c\h文件

:AT 新建一个标签页并打开c\h文件

9、自动补全

vim也可以做到完美的代码补全。但是该功能要tags文件的支持。为了实现自动补全功能,你需要在~/.vimrc文件中增加下面两句:

filetype plugin indent on # 打开文件类型检测,加了这句才可以用智能补全

set completeopt=longest,menu # 关掉智能补全时的预览窗口

保证生成的tags文件已经可以用之后,我们就可以使用代码补全功能了。.

用vim打开一个源文件。可以随便找一个有成员变量的对象, 比如"good", 进入Insert模式, 将光标放在"->"后面,然后按下"Ctrl+X
Ctrl+O" (居然要按四个键),此时会弹出一个下列菜单, 显示所有匹配的标签。此时有一些快捷键可以用:

l Ctrl+P 向前切换成员

l Ctrl+N 向后切换成员

l Ctrl+E 表示退出下拉窗口, 并退回到原来录入的文字

l Ctrl+Y 表示退出下拉窗口, 并接受当前选项

如果你增加了一些成员变量, 全能补全还不能马上将新成员补全, 需要你重新生成一下tags文件, 但是你不用重启vim,只是重新生成一下tags文件就行了, 这时全能补全已经可以自动补全了。

vim中的其他补全方式还有:

l Ctrl+X
Ctrl+L 整行补全

l Ctrl+X
Ctrl+N 根据当前文件里关键字补全

l Ctrl+X
Ctrl+K 根据字典补全

l Ctrl+X
Ctrl+T 根据同义词字典补全

l Ctrl+X
Ctrl+I 根据头文件内关键字补全

l Ctrl+X
Ctrl+] 根据标签补全

l Ctrl+X
Ctrl+F 补全文件名

l Ctrl+X
Ctrl+D 补全宏定义

l Ctrl+X
Ctrl+V 补全vim命令

l Ctrl+X
Ctrl+U 用户自定义补全方式

l Ctrl+X
Ctrl+S 拼写建议

Cscope使用补充 一

cscope使用

1、 建立cscope使用的索引文件

在你需要浏览源码的根目录下使用下面命令:

# cscope –Rbkq <回车>

l R 表示把所有子目录里的文件也建立索引

l b 表示cscope不启动自带的用户界面,而仅仅建立符号数据库

l q生成cscope.in.out和cscope.po.out文件,加快cscope的索引速度

l k在生成索引文件时,不搜索/usr/include目录

在源码根目录下打开任意.c文件,使用如下命令:

l Ctrl+]:将跳到光标所在变量或函数的定义处,Ctrl+T返回

l cs
find s ---- 查找C语言符号,即查找函数名、宏、枚举值等出现的地方

l cs
find g ---- 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能

l cs
find d ---- 查找本函数调用的函数

l cs
find c ---- 查找调用本函数的函数

l cs
find t ---- 查找指定的字符串

l cs
find e ---- 查找egrep模式,相当于egrep功能,但查找速度快多了

l cs
find f ---- 查找并打开文件,类似vim的find功能

l cs
find i ---- 查找包含本文件的文件

2、 cscope的所有命令也可以且按键来实现

Ctrl+\ 再按 s 表示:cs
find s命令,同理实现cs find + g,d,c,t,e,f,i命令。cscope_map.vim说明:

有英文注释的我就不说明了,我就说一下里边的键map映射:

如: nmap <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>

1) nmap 表示在vim的普通模式下,即相对于:编辑模块和可视模式。以下是几种模式:

l map 普通,可视模式及操作符等待模式

l :vmap 可视模式

l :omap 操作符等待模式

l :map! 插入和命令行模式

l :imap 插入模式

l :cmap 命令行模式

<C-\>表示:Ctrl+\

2) s表示输入(即按:s)s

3) : 表示输入':'

4) “cs
find s"表示输入"cs find s"也即是要输入的命令

5) <C-R>=expand("cword")总体是为了得到:光标下的变量或函数。cword 表示:cursor
word, 类似的

还有:cfile表示光标所在处的文件名。

将下面的内容添加到~/.vimrc中, 并重启vim:

nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR>

nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR>

nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR>

nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR>

nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR>

nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR>

nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>

nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>

当光标停在某个你要查找的词上时, 按下<C-_>g, 就是查找该对象的定义, 其他的同理。按这种组合键有一点技巧,按了<C-_>后要马上按下一个键,否则屏幕一闪就回到nomal状态了。<C-_>g的按法是先按"Ctrl+Shift+-", 然后很快再按"g" 。

Cscope使用补充 二

Using Cscope on large projects (example: the Linux kernel)

http://zqwt.012.blog.163.com/blog/static/1204468420115203531294/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: