vim作为linux下的必备文本编辑工具,必须掌握,网上教程很多,就不列举了。这里有一份简明vim练级攻略,不熟悉的请自行学习。
ctags工具是用来遍历源代码文件生成tags文件,这些tags文件能被编辑器或其它工具用来快速查找定位源代码中的符号(tag/symbol),如变量名,函数名等。
sudo apt-get install ctags
http://ctags.sourceforge.net/
ctags的使用很简单,vim已经内置了对ctags的支持。
首先在源代码根目录执行ctags -R,递归的为源码建立tags,在根目录会生成一个tags的文件,里面存放了各种函数和变量的tag,用于阅读时的跳转。
:set tags=tags文件的路径
这时就可以使用tags的功能进行跳转阅读了,常用ctags跳转命令后面给出。
set tags=./tags;,tags
“./tags;”表示循环向上递归寻找tags文件
这里列举一些常用命令(等我遇到其他常用的再来补充)
命令 | 作用 |
---|---|
Ctrl + ] | 使光标在函数或变量上,即可跳转到其定义处 |
Ctrl + t | 回到你跳转之前的位置 |
对于简单的代码,ctags就够用了,但是对于比较复杂的代码来说,ctags显得有点力不从心,所以我们需要功能更多的cscope;vim同样内置了对cscope的支持。
sudo apt-get install cscope
http://cscope.sourceforge.net/
首先在源代码根目录执行cscope -Rbq,就会生成cscope.out文件(索引数据库)
参数 | 作用 |
---|---|
-R | 在生成索引文件时,搜索子目录树中的代码 |
-b | 只生成索引文件,不进入cscope的界面 |
-q | 生成cscope.in.out和cscope.po.out文件,加快cscope的索引速度 |
cscope.out是cscope索引的数据库,要将其加入到vim中去
然后就可以使用cscope命令进行查找了,命令稍后给出
在.vimrc中进行配置,令其自动寻找cscope.out文件位置,这里给出一份配置如下:
" Vim global plugin for autoloading cscope databases.
" Last Change: Wed Jan 26 10:28:52 Jerusalem Standard Time 2011
" Maintainer: Michael Conrad Tadpol Tilsra
" Revision: 0.5
if exists("loaded_autoload_cscope")
finish
endif
let loaded_autoload_cscope = 1
" requirements, you must have these enabled or this is useless.
if( !has('cscope') || !has('modify_fname') )
finish
endif
let s:save_cpo = &cpo
set cpo&vim
" If you set this to anything other than 1, the menu and macros will not be
" loaded. Useful if you have your own that you like. Or don't want my stuff
" clashing with any macros you've made.
if !exists("g:autocscope_menus")
let g:autocscope_menus = 1
endif
"==
" windowdir
" Gets the directory for the file in the current window
" Or the current working dir if there isn't one for the window.
" Use tr to allow that other OS paths, too
function s:windowdir()
if winbufnr(0) == -1
let unislash = getcwd()
else
let unislash = fnamemodify(bufname(winbufnr(0)), ':p:h')
endif
return tr(unislash, '\', '/')
endfunc
"
"==
" Find_in_parent
" find the file argument and returns the path to it.
" Starting with the current working dir, it walks up the parent folders
" until it finds the file, or it hits the stop dir.
" If it doesn't find it, it returns "Nothing"
function s:Find_in_parent(fln,flsrt,flstp)
let here = a:flsrt
while ( strlen( here) > 0 )
if filereadable( here . "/" . a:fln )
return here
endif
let fr = match(here, "/[^/]*$")
if fr == -1
break
endif
let here = strpart(here, 0, fr)
if here == a:flstp
break
endif
endwhile
return "Nothing"
endfunc
"
"==
" Cycle_macros_menus
" if there are cscope connections, activate that stuff.
" Else toss it out.
" TODO Maybe I should move this into a seperate plugin?
let s:menus_loaded = 0
function s:Cycle_macros_menus()
if g:autocscope_menus != 1
return
endif
if cscope_connection()
if s:menus_loaded == 1
return
endif
let s:menus_loaded = 1
set csto=0
set cst
silent! map s :cs find s =expand("")
silent! map g :cs find g =expand("")
silent! map d :cs find d =expand("")
silent! map c :cs find c =expand("")
silent! map t :cs find t =expand("")
silent! map e :cs find e =expand("")
silent! map f :cs find f =expand("")
silent! map i :cs find i =expand("")
if has("menu")
nmenu &Cscope.Find.Symbols
\ :cs find s =expand("")
nmenu &Cscope.Find.Definitiong
\ :cs find g =expand("")
nmenu &Cscope.Find.Calledd
\ :cs find d =expand("")
nmenu &Cscope.Find.Callingc
\ :cs find c =expand("")
nmenu &Cscope.Find.Assignmentt
\ :cs find t =expand("")
nmenu &Cscope.Find.Egrepe
\ :cs find e =expand("")
nmenu &Cscope.Find.Filef
\ :cs find f =expand("")
nmenu &Cscope.Find.Includingi
\ :cs find i =expand("")
" nmenu &Cscope.Add :cs add
" nmenu &Cscope.Remove :cs kill
nmenu &Cscope.Reset :cs reset
nmenu &Cscope.Show :cs show
" Need to figure out how to do the add/remove. May end up writing
" some container functions. Or tossing them out, since this is supposed
" to all be automatic.
endif
else
let s:menus_loaded = 0
set nocst
silent! unmap s
silent! unmap g
silent! unmap d
silent! unmap c
silent! unmap t
silent! unmap e
silent! unmap f
silent! unmap i
if has("menu") " would rather see if the menu exists, then remove...
silent! nunmenu Cscope
endif
endif
endfunc
"
"==
" Unload_csdb
" drop cscope connections.
function s:Unload_csdb()
if exists("b:csdbpath")
if cscope_connection(3, "out", b:csdbpath)
let save_csvb = &csverb
set nocsverb
exe "cs kill " . b:csdbpath
set csverb
let &csverb = save_csvb
endif
endif
endfunc
"
"==
" Cycle_csdb
" cycle the loaded cscope db.
function s:Cycle_csdb()
if exists("b:csdbpath")
if cscope_connection(3, "out", b:csdbpath)
return
"it is already loaded. don' t try to reload it.
endif
endif
let newcsdbpath = s:Find_in_parent("cscope.out",s:windowdir(),$HOME)
" echo "Found cscope.out at: " . newcsdbpath
" echo "Windowdir: " . s:windowdir()
if newcsdbpath != "Nothing"
let b:csdbpath = newcsdbpath
if !cscope_connection(3, "out", b:csdbpath)
let save_csvb = &csverb
set nocsverb
exe "cs add " . b:csdbpath . "/cscope.out " . b:csdbpath
set csverb
let &csverb = save_csvb
endif
"
else " No cscope database, undo things. (someone rm-ed it or somesuch)
call s:Unload_csdb()
endif
endfunc
" auto toggle the menu
augroup autoload_cscope
au!
au BufEnter *.[chly] call <SID>Cycle_csdb() | call <SID>Cycle_macros_menus()
au BufEnter *.cc call <SID>Cycle_csdb() | call <SID>Cycle_macros_menus()
au BufUnload *.[chly] call <SID>Unload_csdb() | call <SID>Cycle_macros_menus()
au BufUnload *.cc call <SID>Unload_csdb() | call <SID>Cycle_macros_menus()
augroup END
let &cpo = s:save_cpo
上面的配置文件不仅仅递归循环查找cscope.out的位置,还设置了一些快捷键,可以修改里面的配置将其关掉。
更多的配置方式可以参考vim网站中的模板。
在vim中可以使用cscope的命令进行查找,格式如下(x代表查询选项,var表示要查找的函数或变量名):
:cs find x var
cscope支持8种查询方式
查询选项 | 效果 |
---|---|
s | 查找C语言符号,即查找函数名、宏、枚举值等出现的地方 |
g | 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能 |
d | 查找本函数调用的函数 |
c | 查找调用本函数的函数 |
t | 查找指定的字符串 |
e | 查找egrep模式,相当于egrep功能,但查找速度快多了 |
f | 查找并打开文件,类似vim的find功能 |
i | 查找包含本文件的文件 |
同样的Ctrl+O返回。
有空再研究
以上方式仅仅是为了在vim中阅读源码,如果是在windows平台下,sourceinsight才是最好的选择。