一.ctags 安装和配置
首先要说的是ctags是一个linux上很普遍的源码分析工具, 可以将代码中的函数变量等定义的位置记录在一个名称为tags的文件. 类似于数据库记录功能. tags文件的产出最简单的方法是在需要生成tags的工程项目的根目录下执行ctags -R命令, 这会调用tags递归的扫描当前目录以及所有子目录中可以被tags识别的文件所以文件数据信息都会汇集到tags文件中.这里总结一下几个本人暂时知道的几个需要注意的地方:
->ubuntu在默认系统环境中已经集成了ctags功能, 但这个ctags并不是完整的版本, 为了保证vim可正常的使用tags建议安装完整的ctags支持, ubuntu完整的ctags被重名为exuberant-ctags但依然可以通过ctags索引到, 安装命令如下:
sudo apt-get install ctags
->如果你的vim有使用echofunc插件来显示函数的参数定义, 那么在使用ctags生产索引文件时需要使用如下附加参数:
ctags -R --fields=+lS
->ctags默认生成的索引文件只包含了对C语言的语法分析, 如果你需要ctags支持对C++语法分析. 需要使用下面的命令:
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q
->如果同时支持上面两个使用场景,需要使用下面的命令:
ctags -R --c++-kinds=+p --fields=+liaS --extra=+q
->如果你在C语言编写的代码中使用上面提到的C++命令生成tags, 那么你将惊讶的发现, 当你希望通过ctags跳转到光标下函数定义的地方的时候, vim总是跳转到这个函数定义的地方, 原因是ctags的C++命令增加了额外的语法分析以便支持C++更加复杂的语法结构, 这种额外的语法分析用在C语言中的时候就会出现跳转默认定位到函数声明的地方.
->ctags默认是支持C和C++的由于本人暂时没有做过其他语言的开发工作, 所以不清楚ctags是否支持其他编程语言.
->请不要每次生成tags的时候都使用上面的命令, 包括以后其他的很多功能的实现都是如此, 命令是实现一个功能的原型, 如果仅仅使用命令在类unix(windows下面也是如此)的操作系统上实现常用的操作和功能, 那么你的操作将会变得很低效. 个人认为vim的使用也有这个规律, 最普遍的操作最好不要使用长长的命令来实现. 取而代之的方法是设置快捷键和命令的简写映射.
二. ctags 在 vim中的使用
vim配置tags使用的过程是, 先在终端中生成一个项目的tags文件, 再在vimrc中告诉vim哪里去找这个tags. 假如我们有一个项目在/home/boddy/hello/下面, 并且这个目录下已经生成tags文件.那么只要在vimrc文件中添加如下语句就可以让vim在每次启动的时候自动找到这tags了:
set tags+=/home/boddy/holle/tags
如果你有多个tags需要使用,可以重复上面的语句, 也可以在同一个语句中加入多个路径,每个路径用","隔开.
这种方法是我最初使用tags的的方式, 缺点显而易见, 每当我们开始新的项目的时候,不得不重新修改set tags后面的路径, 虽然这样的修改并不麻烦, 也不需要经常操作. 但不免还是让人觉得太死板不智能.
为了让vim对tags的支持更加自动话, 首先想到的方法是在vimrc中添加 settags+=./tags语句, 这样当前目录下的tags就不需要我们手动添加了.但我们不可能永远在项目的根目录操作. 如果在项目的子目录里操作, 这个方法将会失效. 事实上, 任何一个项目文件夹都有一个显著的特点: 任何子目录递归向上都可以到达项目的根目录. 这个特点将会在下面的实践中大显身手, 让我们从各种和项目整体相关的操作中解脱出来. 这包括ctags cscope lookupfile等相关索引文件的自动添加和随时更新. 在项目任意子目录下的任意时刻对项目的自动make和make clean等. 这些最频繁操作要么是自动完成的要么是通过vimrc的map功能映射到不同的快捷键上, 这会让我们的vim具有所以IDE所具有的便捷性的同时保持了vim在编码方面无比的高校性和在功能定制方便的无比的可定制性. 我想这就是我为什么宁愿选择折腾vim而没有使用成熟的IDE的原因.
上面提到工程项目的目录递归特性, 实际上, 我们需要使用一个tags最典型的需求是希望在一个项目中快速的找到函数,变量,宏等定义的地方. 这些查找大多是在项目文件夹内完成. 因此, 只要我们能上vim实现对当前所在目录的递归查找功能, 这个需求就会满足. 只要项目的根目录下存在tags文件, 任何时候任在任何一个项目的子目录下使用vim都可以正确的找到这个tags, 同时如果我们的电脑中存在多个项目, 当我们切换到另一个项目的子目录的时候, vim递归查找到永远是当前项目根目录下面的tags(前提是tags存在于项目根目录), 无意间就实现tags的自动切换功能.
实现vim对tags的自动递归查找其实很简单, 因为vim已经实现了这个功能, 只是默认没有开启. 在vimrc添加下面两行配置, 就会是见证奇迹的时刻:
set autochdir
set tags=tags;
set autochdir表示自动切换目录的意思, set tags=tags;表示自动查找, 这两句同时设置vim即可实现递归的tags查找, 注意: set tags=tags;这一句的最后有一个分号, 这个分号是不能省略的. vim的配置文件使用的是vim自己的脚步语言. 这里是少数几个在行尾需要使用分号的地方之一.
最后需要说明的一点: ctags在默认的命令下生成的tags中使用的是相对路径的存放所有查找结果, 这在多数情况下是一个优点, 因为相对路径不依赖于项目的根目录所在位置. 这样在整个项目转移到别的位置的时候, 相对路径的tags依然可以正常的实现跳转. 不过相对路径的tags并不是没有缺点, 如果你的vim中使用了FuzzyFinder来作为查找项目文件的工具, 你将惊讶的发现如果你在项目根目录的子目录下执行项目文件查找,在找到了想要的文件并最后回车跳转的时候如果tags使用的是相对路径, 这一步将会失败, 因为FuzzyFinder无法正确的通过当前的目录(不是项目根目录)加上tags中的相对路径计算出正确的文件位置. 解决的办法是在ctags生产tags文件的时候使用绝对路径, 使用方法是在ctags -R 的命令后面添加项目根目录的绝对路径, 如: ctags -R /home/boddy/hello/ , 使用绝对路径可以保证tags在任何调用他的工具中正确的找到文件位置. 唯一的缺点是如果项目移动了, tags必需重新生成, 鉴于我们的项目在自己的电脑中移动的需求很小的同时重新生成一tags的时间也就是几秒钟的事情(只要不是超级大的项目,tagseh生成还是很快的), 我个人选择了在任何时候使用ctags都使用绝对路径, 当然这个功能是在vim中通过参数自动实现的, 本文的最后将会提到.
三. cscope的安装和配置
sudo apt-get install cscope
使用ctags生成tags类似,通过下述命令可以生成cscope.out[2]:
在当前目录中生成cscope.out:
(2) 添加额外的目录
指定源码绝对路径,查找时不受当前工作路径的限制:
例如在进行Linux驱动开发的时候,将absoluteDir取为Linux源码所在的目录,然后在驱动项目目录执行上述命令(不是进入Linux源码中哦,而是自己在Linux源码之外所创建的目录)。此时,在进行驱动开发的时候,就可以利用cscope的查找功能了, 而不必将当前目录切换到Linux源码目录中。
(3)添加路径前缀
通过第上述步骤(2)虽然可以达到搜索不受工作路径的影响,但是会有一个副作用:同一个文件会有两个重复的路径,一个相对路径,一个绝对路径。因此,在查找的过程中,会出现重复的结果。
为了避免上述副作用,最好是使用下述命令代替上述第(2)步的命令,同样可以达同样的目的,并避免了副作用:
-P,表示为搜索路径添加前缀, pwd是获取当前工作路径的命令。
3.2 添加目录/库文件
(1)手动方式
打开vim之后,可以通过下述命名添加目录
(2)自动方式一
也可以将下面语句添加到vim的配置文件.vimrc中
这样子就会在打开vim的时候自动加载当前目录下车cscope.out文件。
(3)自动方式二
autoload_cscope.vim插件更方便,它会先在当前目录查找cscope.out,有则加载,否则进入其父目录查找,直到找到可用的cscope.out为止。
四、cscope 的使用
3.3 find命令
Cscope的功能通过它的子命令find来实现。
为了便于查找,根据参考资料[4][5]的提示,可以在.vimrc中设置上述各命令的快捷映射:
使用时,将光标停留在要查找的对象上,按下Ctrl + g,将会查找该对象的定义(这里使用Ctrl是为了避免和vim的原有快捷方式冲突);其它的快捷方式使用如Shift+ s/c/t/e/f/i/d。
五,在coding过程中,有了变量或函数的自动弹出功能,可以极大的提高编码的效率和准确率,这里介绍的AutoComplPop和OmniCppComplete脚本插件就是实现这样一个功能。
1. 代码(普通变量函数)的自动弹出 AutoComplPop
下载:http://www.vim.org/scripts/script.php?script_id=1879
安装:
先解压:unzip vim-autocomplpop.zip
同其他脚本插件的安装方法一致,将解压后的文件拷贝到~/.vim/ 下的相应目录里:
autoload/* -> ~/.vim/autoload/
doc/* -> ~/.vim/doc/
plugin/* -> ~/.vim/plugin/
使用:
重新打开vim即可使用。添加help文件:helptags ~/.vim/doc/即可(打开帮助文件:h(elp) autocomplpop)
效果图:
2. c/c++代码(类的 . , ->, :: 操作符)的自动补全 OmniCppComplete
下载:http://www.vim.org/scripts/script.php?script_id=1520
安装:
先解压:unzip omnicppcomplete-0.41.zip
同其他脚本插件的安装方法一致,将解压后的文件拷贝到~/.vim/ 下的相应目录里:
autoload/* -> ~/.vim/autoload/
doc/* -> ~/.vim/doc/
after/* -> ~/.vim/after/
使用:
重新打开vim,添加help文件:helptags ~/.vim/doc/(打开帮助文件:h(elp) omnicppcomplete),但其功能的展现还需要一下操作和设置:
omnicppcomplete脚本插件的基本设置,在~/.vimrc中添加(我的喜好设置):
set completeopt=menu,menuone
let OmniCpp_MayCompleteDot=1 “ 打开 . 操作符
let OmniCpp_MayCompleteArrow=1 "打开 -> 操作符
let OmniCpp_MayCompleteScope=1 ”打开 :: 操作符
let OmniCpp_NamespaceSearch=1 “打开命名空间
let OmniCpp_GlobalScopeSearch=1
let OmniCpp_DefaultNamespace=["std"]
let OmniCpp_ShowPrototypeInAbbr=1 “打开显示函数原型
let OmniCpp_SelectFirstItem = 2”自动弹出时自动跳至第一个
要生成专用于c/c++的ctags文件,并引导vim找到改tags文件:
tags文件生成命令(通常位于代码项目的最上层目录下执行)[admin@local]$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q
引导omnicppcomplete找到tags文件:
(1)在vim中设置:set tags+=/home/project/project_1/tags 。该方法不方便,每次使用都要set一下
(2)在~/.vimrc中添加常用的路径tags:
set tags+=/home/project/project_1/tags
set tags+=/home/project/project_2/tags
这样,每次打开vim便会自动寻找以上设置的tags文件。另外,可以通过vim中:set tags来查看已设置的tags文件路径。
效果图:
六、在vim中加入echofunc这个可以自动提示函数原型的插件,最先版可以通过以下链接下载:
http://www.vim.org/scripts/script.php?script_id=1735
该插件主要是解决omnicppcomplete不能补全函数的问题,基本上也不用配置,主要是在.vimrc中定义两个快捷键来切换函数的不同定义。
安装: | 把下载下来的 echofunc.vim 放到 $HOME/.vim/plugin 目录下。 |
帮助: | 请看 echofunc.vim 的开头部分。 |
插件 echofunc 依赖于另一个插件 ctags 。创建 tags 文件时使用以下命令:
$ ctags -R --fields=+lS