提供一个可以方便的在linux下查看源码,并且学习成本低,使用复杂度低的vim配置。
不用插件
如果你不想使用任何插件,那么下面的配置基本上够用。
" 环境
set nocompatible
" 通用
set background=dark
syntax on
filetype off
set autochdir
" UI
set cursorline
set linespace=0
set number
set showmatch
set incsearch
set hlsearch
set ignorecase
set smartcase
" 编码
set encoding=utf-8
" 格式
set autoindent
set shiftwidth=4
set expandtab
set tabstop=4
set softtabstop=4
set cindent
set smartindent
使用通用插件
基本上是所有linux都自带的,不需要额外安装的插件,也就是说只需要在.vimrc里面配置几行参数就可以直接使用。
ctags
ctags 在使用vim编程和浏览代码是非常有用,在变量或函数处 ctrl+] 来跳转到变量或者函数定义的地方。ctrl+t返回到跳转前的位置。或者使用命令:tag func_nameshi 来跳转到变量或者函数定义的地方。ctags不会生成局部变量的索引,:tags会列出查找/跳转过程。
用法
生成自己工作目录的tags,最简单粗暴用法:
cd yourworkdir
ctags -R *
这样会生成一个tags文件。不过,这种有个问题,成员变量没有包含在里面。所以自动完成对象的成员时没有提示。解决办法:
ctags -R --fields=+iaS --extra=+q *
–fields=[+|-]flags
–fields指定tags的可用扩展域(extension fields),以包含到tags入口。
i:继承信息Inheritance information
a:类成员的访问控制信息 Access (or export) of class members
S: 常规签名信息,如原型或参数表 Signature of routine(e.g. prototype or parameter list)
–extra=[+|-]flags
–extra指定是否包含某种扩展信息到tags入口。
q:包含类成员信息(如c++,java,Eiffel)。
但就算是C 语言的结构,也需要这两个参数设置才能获取成员信息,这样就能自动完成结构和类的成员了。
配置
用户vim配置文件~/.vimrc添加生成的tags文件查询规则:
set tags=./tags;,tags
局限性
tags文件只能查看函数,类或变量的定义,而没有被调用信息。如果要知道一个函数在什么地方被使用,需要使用cscope工具。添加的tags最好是source code的索引,对于include头文件索引没有效果。
cscope
cscope是一个类似ctags的工具。ctags利用tag文件,跳转到标签定义的地方。但如果想查找函数在哪里被调用,或者标签在哪些地方出现过,ctags就无能为力了,这时需要使用更为强大的cscope。
用法
cscope的用法很简单,首先需要为你的代码生成一个cscope数据库。在你的项目根目录运行下面的命令:
cscope -Rbq
这些选项的含义见后面。这个命令会生成三个文件:cscope.out, cscope.in.out, cscope.po.out。其中cscope.out是基本的符号索引,后两个文件是使用”-q“选项生成的,可以加快cscope的索引速度。在缺省情况下,cscope在生成数据库后就会进入它自己的查询界面,我们一般不用这个界面,所以使用了”-b“选项。如果你已经进入了这个界面,按CTRL-D退出。cscope在生成数据库中,在你的项目目录中未找到的头文件,会自动到/usr/include目录中查找。如果你想阻止它这样做,使用”-k“选项。
cscope缺省只解析C文件(.c和.h)、lex文件(.l)和yacc文件(.y),虽然它也可以支持C++以及Java,但它在扫描目录时会跳过C++及Java后缀的文件。如果你希望cscope解析C++或Java文件,需要把这些文件的名字和路径保存在一个名为cscope.files的文件。当cscope发现在当前目录中存在cscope.files时,就会为cscope.files中列出的所有文件生成索引数据库。通常我们使用find来生成cscope.files文件。
find . -name "*.h" -o -name "*.c" -o -name "*.cpp" -o -name "*.cc" > cscope.files
cscope -bkq -i cscope.files
上面的cscope命令并没有使用”-R“参数递归查找子目录,因为在cscope.files中已经包含了子目录中的文件。
注1:find命令输出的文件以相对路径表示,所以cscope.out的索引也相对于当前路径。如果你要在其它路径中使用当前的cscope.out,需要使用下面介绍的-P选项。
注2:cscope只在第一次解析时扫描全部文件,以后再调用cscope,它只扫描那些改动过的文件,这大大提高了cscope生成索引的速度。
常用选项
-R: 在生成索引文件时,搜索子目录树中的代码
-b: 只生成索引文件,不进入cscope的界面
-q: 生成cscope.in.out和cscope.po.out文件,加快cscope的索引速度
-k: 在生成索引文件时,不搜索/usr/include目录
-i: 如果保存文件列表的文件名不是cscope.files时,需要加此选项告诉cscope到哪儿去找源文件列表。可以使用”–“,表示由标准输入获得文件列表。
-I dir: 在-I选项指出的目录中查找头文件
-u: 扫描所有文件,重新生成交叉索引文件
-C: 在搜索时忽略大小写
-P path: 在以相对路径表示的文件前加上的path,这样,你不用切换到你数据库文件所在的目录也可以使用它了。
在vim中使用cscope非常简单,首先调用”cscope add“命令添加一个cscope数据库,然后就可以调用”cscope find“命令进行查找了。
8种查询功能
s: 查找C语言符号,即查找函数名、宏、枚举值等出现的地方
g: 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能
d: 查找本函数调用的函数
c: 查找调用本函数的函数
t: 查找指定的字符串
e: 查找egrep模式,相当于egrep功能,但查找速度快多了
f: 查找并打开文件,类似vim的find功能
i: 查找包含本文件的文件
源代码中查找调用test()函数的函数,我们可以输入:”:cs find c test“,回车后发现没有找到匹配的功能,可能并没有函数调用test()。我们再输入”:cs find s test“,查找这个C符号出现的位置,现在vim列出了这个符号出现的所有位置。我们还可以进行字符串查找,它会双引号或单引号括起来的内容中查找。还可以输入一个正则表达式,这类似于egrep程序的功能,但它是在交叉索引数据库中查找,速度要快得多。
注3:现在版本linux上的vim默认都支持cscope,在/etc/vimrc可以看到有如下配置:
if has("cscope") && filereadable("/usr/bin/cscope")
set csprg=/usr/bin/cscope
set csto=0
set cst
set nocsverb
" add any database in current directory
if filereadable("cscope.out")
cs add cscope.out
" else add database pointed to by environment
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
set csverb
endif
配置
用户vim配置文件~/.vimrc添加快捷键映射:
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>
使用其他插件
下面这几个插件也是看代码必须的,非常有用,但是需要额外安装,安装方法十分简单。先安装bundle,这个教程网上到处都有。然后基于bundle就可以轻松安装taglist和nertree了。到此为止就算配完了,非常简单。
安装bundle
用来进行插件管理的插件,安装后可以方便的安装下面taglist和nertree等插件。通过Git自动从远程创库同步插件安装包到本地仓库(Vundle的默认本地仓库位置是~/.vim/bundle/) 通过Git下载Vundle安装包:
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
安装好后, 在~/.vimrc中添加Vundle的配置内容:
set nocompatible " be iMproved, required
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')
" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'
" The following are examples of different formats supported.
" Keep Plugin commands between vundle#begin/end.
" plugin on GitHub repo
Plugin 'tpope/vim-fugitive'
" plugin from http://vim-scripts.org/vim/scripts.html
" Plugin 'L9'
" Git plugin not hosted on GitHub
Plugin 'git://git.wincent.com/command-t.git'
" git repos on your local machine (i.e. when working on your own plugin)
Plugin 'file:///home/gmarik/path/to/plugin'
" The sparkup vim script is in a subdirectory of this repo called vim.
" Pass the path to set the runtimepath properly.
Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}
" Install L9 and avoid a Naming conflict if you've already installed a
" different version somewhere else.
" Plugin 'ascenator/L9', {'name': 'newL9'}
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList - lists configured plugins
" :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line
如果你不想要里面已经配置好的插件,把有PluginList字段的行删除就行,但是Plugin 'VundleVim/Vundle.vim'
这个不能删除。
安装其他插件
taglist
基于ctags,在vim代码窗口旁以分割窗口形式显示当前的代码结构概览的插件。.vimrc的配置为:
Bundle 'taglist.vim'
let Tlist_Ctags_Cmd='ctags'
let Tlist_Show_One_File=1 "不同时显示多个文件的tag,只显示当前文件的
let Tlist_WinWidt =28 "设置taglist的宽度
let Tlist_Exit_OnlyWindow=1 "如果taglist窗口是最后一个窗口,则退出vim
"let Tlist_Use_Right_Window=1 "在右侧窗口中显示taglist窗口
let Tlist_Use_Left_Windo =1 "在左侧窗口中显示taglist窗口
nerdtree
能够在vim下浏览文件系统的所有文件,并能够打开文件的插件。.vimrc的配置为:
Bundle 'scrooloose/nerdtree'
let NERDTreeWinPos='left'
let NERDTreeWinSize=30
map <F2> :NERDTreeToggle<CR>
配置完.vimrc后,Launch vim and run :PluginInstall,直到左下方状态栏出现Done!
一些经验
基本上有了上述插件,看自己开发目录的项目源码是不成问题了。而且整个配置下来也不复杂,比较容易理解和掌握。有的配置虽然用起来很方便,但是复杂度不是一点半点,反倒适得其反。基本原则有两条:
- 不要把系统相关的源码或者庞大的第三方库源码也用ctags或者cscope处理带进源码阅读,干扰视听,保持查看代码的最小化。
- linux编程常用函数可以通过shift+k去进行查看,凡是通过man命令可以看的都可以通过shift+k跳转。