一. vim
vim作为linux下的必备文本编辑工具,必须掌握,网上教程很多,就不列举了。这里有一份简明vim练级攻略,不熟悉的请自行学习。
二. ctags
ctags工具是用来遍历源代码文件生成tags文件,这些tags文件能被编辑器或其它工具用来快速查找定位源代码中的符号(tag/symbol),如变量名,函数名等。
安装
- 这里先给出ubuntu下的安装
sudo apt-get install ctags
- 或者是下载源码自行安装
http://ctags.sourceforge.net/
使用准备
ctags的使用很简单,vim已经内置了对ctags的支持。
首先在源代码根目录执行ctags -R,递归的为源码建立tags,在根目录会生成一个tags的文件,里面存放了各种函数和变量的tag,用于阅读时的跳转。
使用
方法一
- 使用vim打开你要阅读的源码,在vim中的命令模式下导入tags标签
:set tags=tags文件的路径
这时就可以使用tags的功能进行跳转阅读了,常用ctags跳转命令后面给出。
方法二
- 每次手动导入tags所在目录相当麻烦,而且还只能在ctags文件所在目录进行操作,正确姿势应该是写入.vimrc文件,自动从当前目录递归向上寻找。在你的主目录下的.vimrc文件中写入以下命令:
set tags=./tags;,tags
“./tags;”表示循环向上递归寻找tags文件
命令
这里列举一些常用命令(等我遇到其他常用的再来补充)
命令 | 作用 |
---|---|
Ctrl + ] | 使光标在函数或变量上,即可跳转到其定义处 |
Ctrl + t | 回到你跳转之前的位置 |
三. cscope
对于简单的代码,ctags就够用了,但是对于比较复杂的代码来说,ctags显得有点力不从心,所以我们需要功能更多的cscope;vim同样内置了对cscope的支持。
安装
- ubuntu下的安装
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中去
方法一
- 使用vim打开文件
- 在vim命令中执行:cs add [cscope.out文件位置],添加数据库
然后就可以使用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 <tadpol@tadpol.org>
" 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 <unique> <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>
silent! map <unique> <C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
silent! map <unique> <C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
silent! map <unique> <C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
silent! map <unique> <C-\>t :cs find t <C-R>=expand("<cword>")<CR><CR>
silent! map <unique> <C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
silent! map <unique> <C-\>f :cs find f <C-R>=expand("<cword>")<CR><CR>
silent! map <unique> <C-\>i :cs find i <C-R>=expand("<cword>")<CR><CR>
if has("menu")
nmenu &Cscope.Find.Symbol<Tab><c-\\>s
\ :cs find s <C-R>=expand("<cword>")<CR><CR>
nmenu &Cscope.Find.Definition<Tab><c-\\>g
\ :cs find g <C-R>=expand("<cword>")<CR><CR>
nmenu &Cscope.Find.Called<Tab><c-\\>d
\ :cs find d <C-R>=expand("<cword>")<CR><CR>
nmenu &Cscope.Find.Calling<Tab><c-\\>c
\ :cs find c <C-R>=expand("<cword>")<CR><CR>
nmenu &Cscope.Find.Assignment<Tab><c-\\>t
\ :cs find t <C-R>=expand("<cword>")<CR><CR>
nmenu &Cscope.Find.Egrep<Tab><c-\\>e
\ :cs find e <C-R>=expand("<cword>")<CR><CR>
nmenu &Cscope.Find.File<Tab><c-\\>f
\ :cs find f <C-R>=expand("<cword>")<CR><CR>
nmenu &Cscope.Find.Including<Tab><c-\\>i
\ :cs find i <C-R>=expand("<cword>")<CR><CR>
" nmenu &Cscope.Add :cs add
" nmenu &Cscope.Remove :cs kill
nmenu &Cscope.Reset :cs reset<cr>
nmenu &Cscope.Show :cs show<cr>
" 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 <C-\>s
silent! unmap <C-\>g
silent! unmap <C-\>d
silent! unmap <C-\>c
silent! unmap <C-\>t
silent! unmap <C-\>e
silent! unmap <C-\>f
silent! unmap <C-\>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返回。
四. taglist
有空再研究
建议
以上方式仅仅是为了在vim中阅读源码,如果是在windows平台下,sourceinsight才是最好的选择。