六,、通用的使用 VIM+Ctags+Cscope 訪問程序文件的方法
1. ctags+cscope配合使用的原因:
為什么要配合,因?yàn)?,比如cscope能提供更多的查找功能等功能,。但是ctags遠(yuǎn)比cscope支持更多的文件。比如要訪問一個(gè)java工程文件,,那么cscope是能力低下的,,比如對(duì)類識(shí)別不行,但是我們?nèi)匀豢梢岳闷湟恍┕δ?,比如找到什么函?shù)調(diào)用了這個(gè)函數(shù),。
另外,還有點(diǎn)注意,,ctags不能利用QuickFix窗口,而cscope可以利用,,這也是cscope的好處,。一般,如果僅僅有C/C++文件,用cscope更多,,如果是其他文件,,則用ctags更多。
不管是用ctags還是cscope,,都可以用WinManager和Taglist,,來實(shí)現(xiàn)左邊上面是文件列表,下面是Taglist,,右邊是文件瀏覽窗口的效果,!但是Taglist依賴ctags,如果用cscope,,ctags還是要用的,。具體的讓W(xué)inManager和Taglist配合的方法,見vim配置文件,。
2.
生成數(shù)據(jù)庫并讓vim使用:
一般的做法是:在最上層目錄,,生成這些文件。然后vim在最上層打開,,并利用下面提到的WinManager來導(dǎo)航到里面目錄,。
(1)
ctags生成tags文件:
ctags -R . 可以搜索目錄下所有的文件,并生成 tags
文件,。
為了生成最多的tags:
C/C++這樣:ctags --extra=+q --fields=+Saim --c++-kinds=+lpx
--c-kinds=+lpx -R .
Java這樣:ctags --java-kinds=+l -R
.
(主要是--xx-kinds控制著要分析出哪些東西,,如--java-kinds=+l表示要加上(+)local
variable,默認(rèn)的有哪些,,沒有哪些,,用ctags --list-kinds
可以知道,off的都是默認(rèn)不分析的,,否則是分析的)
cscope只能分析C/C++/lex/yacc文件,!
然后在vim里 :set
tags=path/to/tags(用,分隔,可以多個(gè))
(2) cscope生成cscope.in.out cscope.out
cscope.po.out文件:
由于cscope默認(rèn)不看非.c .yacc
.lex外的文件,,所以,,假設(shè)你要找C和C++其他文件,要這樣:
find . -name "*.h" -o -name "*.c" -o -name
"*.cc" > cscope.files
cscope -bkq -i
cscope.files
(找java文件同理)
而,,對(duì)于純C文件,,你可以:
cscope -Rbkq ./
即可。
然后在vim里 :cs add path/to/cscope.out
如果要重新生成,,用:!cscope -Rbkq,,再用 :cs
reset重新讀入.
3. ctags
管理跳轉(zhuǎn)棧:
ctags設(shè)計(jì)來找到各種希望找的東西,如類定義處,,函數(shù)定義處,。對(duì)各種語言都有支持,,但原設(shè)計(jì)就是針對(duì)function定義的,所以,,ctags對(duì)尋找functions定義特別有效,,像函數(shù)原型是默認(rèn)不做tag的。
(1)
vim的支持tags的命令:(這些命令在編譯時(shí)要加進(jìn)ctags支持才能用)
vim靠?jī)?nèi)置的命令,,來支持使用ctags得到的tags文件,。
:tags
列出目前你跳轉(zhuǎn)的棧,可以得知當(dāng)前位置 (可惜不能用QuickFix窗口)
:tag 跳到:tags列表的頂部(棧底)
:tag tagname
跳到tagname的定義處
Ctrl+] 壓棧(跳到標(biāo)記定義處) Ctrl+W ] 在橫著的新窗口打開(:stag tagname)
n
Ctrl+t 出棧(后跳n次,,會(huì)使你的:tags列出的表縮短) ── 跨文件時(shí),,用 Ctrl + o才能跳回去。
:tselect tagname
可以列出所有的相同的tagname,,你按數(shù)字可以跳到對(duì)應(yīng)條目,。
:tnext 跳到下一個(gè)相同tagname處
:tprevious
同理
:tfirst 同理
:tlast 同理
匹配用/ /來括起來,讓vim知道里面的是正則式
如
:tselect /^write_ 可以匹配以 write 開頭的
:set ignorecase 可以在任何時(shí)候忽略大小寫,,比如在:tag
tagname時(shí),。如果設(shè)置了這個(gè),又想case有效,,則在表達(dá)式后加\C
但如果想某次有效,,則在表達(dá)式后面加\c
上面的表達(dá)式都用//包起來。
4.
cscope看vim配置文件和以前的文檔即可,。
5. 使用Path:
有時(shí),,我們要定義額外的Path,以訪問某些文件,。且方便gf(goto
file,,在normal模式下,按gf,,會(huì)打開光標(biāo)下的文件,,它會(huì)在Path下去搜),find(不支持正則式的搜索,,用法 :find
netrw.vim)等命令,。
path選項(xiàng)定義了一個(gè)目錄列表,在使用gf,,find,,以及CTRL-W
f等命令時(shí),如果使用的是相對(duì)路徑,,那么就會(huì)在path選項(xiàng)定義的目錄列表中查找相應(yīng)的文件,。path選項(xiàng)以逗號(hào)分隔各目錄名。我們依舊以VIM
7.0的源代碼為例(源代碼放在~/src/vim70/目錄中),。
對(duì)于這個(gè)項(xiàng)目,,我們的path選項(xiàng)設(shè)置如下:
set
path=.,/usr/include,,~/src/vim70/**
稍微解釋一下各項(xiàng)的含義,,更詳細(xì)的信息,,請(qǐng)查看path選項(xiàng)的幫助頁:
.
在當(dāng)前文件所在目錄中搜索
/usr/include 在/usr/include目錄中搜索
,,
在當(dāng)前工作路徑中搜索
~/src/vim70/** 在~/src/vim70的所有子目錄樹中進(jìn)行搜索!!
6. 多文件瀏覽采用
MiniBufExplorer:
因?yàn)槭褂昧薟inManager和Taglist,,所以tabe顯得不好用了,用buffer會(huì)更方便,。
但是vim自帶的buffer管理工具只有:ls,
:bnext, :bdelete
等的命令,,這里用MiniBufExplorer.好處是在頂上可視化列出了各個(gè)buffer。仍然用:bnext等命令,。
然后,,在vim中設(shè)置了,用shift+Tab來切換buffer,,挺方便,。
關(guān)閉一個(gè)buffer,而不退出窗口,,在標(biāo)簽上按d,,這是MiniBufExplorer的命令。個(gè)
7.
Taglist
提醒用 s 來切換按名字排序(大寫,,再小寫,,每個(gè)里面按首字母)還是出現(xiàn)次序排序
用 u
來更新list(默認(rèn)可以再次調(diào)用ctags)
另外,在vimrc中設(shè)置了單擊來打開對(duì)應(yīng)位置
8.
WinManager
s來切換按xx排序,,r做反排序
另外,,在各個(gè)窗口間切換,用 Ctrl+方向鍵 更快~~~
9.
vimgrep查找文本 或 Grep插件查找文本:
ctags找到了--list-kinds中指示的東西,,你可以用:tag
tagname找出這些tags,,cscope也找了它可以找的東西,可以用:cs find g/d/c/t/e
tagname找到相應(yīng)的東西,,其中t表示找那個(gè)文本,,尤其是e表示用egrep查找。單都是在cscope的數(shù)據(jù)庫中查找,。
但是,,很多時(shí)候,仍需要對(duì)文件本身搜索,,或者想到某個(gè)特定子目錄搜索,,并支持正則式。
(1)
可以用
:vimgrep命令:
:vimgrep是vim內(nèi)置的grep,,如果你用:grep等,,則是讓vim調(diào)用外部的系統(tǒng)的grep。用:vimgrep的好處是,,不依賴于系統(tǒng)的,,使得各個(gè)系統(tǒng)上都可以用,。但是會(huì)慢點(diǎn),因?yàn)樗鼤?huì)把每個(gè)文件,,放入buffer,,再分析。
用法簡(jiǎn)單:
:vimgrep
/pattern/ path
其中 pattern為正則式,,如 \<main\>表示main單詞
path 為shell元字符式,,如
./SSF/**/*.java 表示搜索SSF目錄下,所有子目錄,,及所有嵌套子目錄的 java文件,。
(2)
也可以用Grep插件,下面命令都支持正則式:
:Grep 在指定的文件查找
:Rgrep 遞歸查找
:Bgrep
在打開的緩沖區(qū)中查找
他會(huì)問你更多信息,,比如哪些文件中查找,,在哪個(gè)目錄中查找,很方便,。
如:
Search for pattern: 時(shí)可以填
\<get_real_path\> (匹配單詞,,而不是字符串)
Search in files: 時(shí)可以填 *.java
10.
高亮文本:
:colorscheme 可以選擇某個(gè)主題。
在.vim里,,自己創(chuàng)建colors doc plugin syntax
四個(gè)目錄,,doc和plugin用戶放plugin的文件和doc文件,syntax用于放置指導(dǎo)語法加亮的文件,,而colors就用于放置高亮主題,。目前我用的是desert主題。
11.
目前用到的插件:
a.vim
color_sample_pack.vim
minibufexpl.vim
taglist.vim
winmanager.vim (winfileexplorer.vim
wintagexplorer.vim)
code_complete.vim
#這個(gè)好好看看它的代碼體吧,,很簡(jiǎn)單,,卻很高效的用tab補(bǔ)全很多東西,如調(diào)用函數(shù)時(shí),,在(后按tab,,就可補(bǔ)出各個(gè)參數(shù)的類型。比如很方便自動(dòng)生成main,,for,,while,#define等,。
grep.vim
NERD_commenter.vim
12. 顏色相關(guān):
首先,,在vim中輸入 :runtime
syntax/colortest.vim
可打印出目前你可以使用的顏色。只有那么幾種,。包括粗體,。所以,這就是終端里使用vim沒有g(shù)vim顏色多,,或者沒有g(shù)vim顏色正常的原因,。但是,,你好好調(diào)整一下,還是能夠滿足自己要求的,。
另外,,各種顏色主題,是不能讓,,如函數(shù),,單獨(dú)高亮的,,因?yàn)檫@需要語法幫助,。這需要你單獨(dú)找語法文件,就是什么東西是函數(shù),,并應(yīng)該高亮為什么顏色,。把語法文件放到
~/.vim/syntax中。
我是從官網(wǎng)下了cpp.vim放到~/.vim/syntax目錄中,,于是.cpp文件可以有更多的高亮了,。
但是,c.vim是我從別的地方找的,,官網(wǎng)上找的c.vim不起作用,,我又不好改。目前用的c.vim如下,,主要加亮了函數(shù)名和C關(guān)鍵字,。而cpp.vim是使用c.vim的,所以默認(rèn)也就讓cpp.vim支持同樣的效果了,。
要讀懂和改這個(gè)簡(jiǎn)單文件,,需要知識(shí)如下:
:hi
命令時(shí)一直都是以圖形介面(gui)為例設(shè)置前景和背景色。由于命令終端對(duì)顏色顯示的限制,,Vim在命令行下可以使用的顏色相對(duì)gui
要少得多,,所以使用:hi命令時(shí)圖形介面和命令行介面的顏色是分開設(shè)置的。對(duì)于黑白終端來說就無所謂顏色了,,而彩色終端用cterm來表示,,前景色就是
“ctermfg”,而背景色是“ctermbg”,。下面是一個(gè)表格:
終端類型 前景色 背景色
注釋
term - - 黑白終端
cterm ctermfg
ctermgb 彩色終端
gui guifg guibg
圖形介面
下面是這個(gè)文件
c.vim
"========================================================
"
Highlight All
Function
"========================================================
syn
match cFunction "\<[a-zA-Z_][a-zA-Z_0-9]*\>[^()]*)("me=e-2
syn
match cFunction "\<[a-zA-Z_][a-zA-Z_0-9]*\>\s*("me=e-1
hi
cFunction gui=NONE
guifg=#B5A1FF
"========================================================
"
Highlight All Math
Operator
"========================================================
" C
math operators
syn match cMathOperator display "[-+\*/%=]"
" C
pointer operators
syn match cPointerOperator display "->\|\."
" C
logical operators - boolean results
syn match cLogicalOperator
display "[!<>]=\="
syn match cLogicalOperator display "=="
" C
bit operators
syn match cBinaryOperator display
"\(&\||\|\^\|<<\|>>\)=\="
syn match cBinaryOperator
display "\~"
syn match cBinaryOperatorError display "\~="
" More C
logical operators - highlight in preference to binary
syn match
cLogicalOperator display "&&\|||"
syn match
cLogicalOperatorError display "\(&&\|||\)="
" Math Operator
hi
cMathOperator guifg=#3EFFE2 ctermfg=lightyellow
hi
cPointerOperator guifg=#3EFFE2 ctermfg=lightyellow
hi
cLogicalOperator guifg=#3EFFE2 ctermfg=lightyellow
hi
cBinaryOperator guifg=#3EFFE2 ctermfg=lightyellow
hi
cBinaryOperatorError guifg=#3EFFE2 ctermfg=lightyellow
hi
cLogicalOperator guifg=#3EFFE2 ctermfg=lightyellow
hi
cLogicalOperatorError guifg=#3EFFE2 ctermfg=lightyellow
"
------------------------ further work ------------------------
" hi cType
ctermfg=green
hi cConditional ctermfg=lightred
hi cRepeat
ctermfg=lightred
hi cStatement ctermfg=lightred
hi cLabel
ctermfg=lightred
"hi cType ctermfg=green
hi cDefine ctermfg=magenta
hi
cUndefine ctermfg=magenta
hi cFunction ctermfg=blue
"
----------------------- 以下的是備查而已 ------------------------
" hi other words
later
" C language keywords.
" For compilers with asm keyword - error if
not c_c_vim_compatible.
syn keyword cKRStatement asm
syn
keyword cGNUStatement __asm__
syn keyword cLabel
case default
syn keyword cConditional if else switch
syn
keyword cRepeat while for do
" C data types
syn
keyword c89Type int long short char void signed unsigned float
double
" These are actually macros that expand to the above.
syn
keyword c99Type bool complex imaginary
syn keyword
cGnuType __label__ __complex__ __volatile__
" C language
structures
syn keyword cStructureType typedef
syn keyword
cStructure struct union enum
" C storage modifiers
syn
keyword c89StorageClass static register auto volatile extern
const
syn keyword cKRStorageClass fortran
syn keyword
c99StorageClass restrict inline
syn keyword cGNUStorageClass
__attribute__
13.
支持tags更新:
見下面綁定在F7上的功能,,就是把ctags和cscope重新更新。
這個(gè)的好處顯然的,,比如你想對(duì)新改的代碼使用code_complete.vim插件中的功能,。
14.
c++補(bǔ)全:
omnicppcomplete
插件很好用。這個(gè)放在~/.vim里后,,注意下面.vimrc文件中對(duì)它的幾行設(shè)置,,否則不太好似,。
15. C-x C-o:
C++
自動(dòng)補(bǔ)全OK了,但是C的函數(shù)怎么補(bǔ)全呢,?,? 在ctags存在的情況下,用C-x C-o吧,,我棒定到F8上去了,,見vimrc. 它比
C-p強(qiáng)的地方是,它會(huì)把函數(shù)的函數(shù)原型也列出來,,方便輸入,,其他的找到的,也會(huì)標(biāo)出類型,。
強(qiáng)烈建議程序員完整的閱讀usr_29.txt和usr_30.txt
----------------------
下面是 2009 03 29 日vimrc文件內(nèi)容:----------------------
" An example for a vimrc
file.
"
" Maintainer: Bram Moolenaar <[email protected]>
" Last
change: 2006 Nov 16
"
" To use it, copy it to
" for Unix and
OS/2: ~/.vimrc
" for Amiga: s:.vimrc
" for MS-DOS and Win32:
$VIM\_vimrc
" for OpenVMS: sys$login:.vimrc
" When started as
"evim", evim.vim will already have done these settings.
if v:progname =~?
"evim"
finish
endif
" Use Vim settings, rather then Vi settings
(much better!).
" This must be first, because it changes other options as a
side effect.
set nocompatible
" allow backspacing over everything in
insert mode
set backspace=indent,eol,start
if has("vms")
set
nobackup " do not keep a backup file, use versions instead
else
set
backup " keep a backup file
endif
set history=50 " keep 50
lines of command line history
set ruler " show the cursor position all
the time
set showcmd " display incomplete commands
set incsearch
" do incremental searching
" For Win32 GUI: remove 't' flag from
'guioptions': no tearoff menu entries
" let &guioptions =
substitute(&guioptions, "t", "", "g")
" Don't use Ex mode, use Q for
formatting
map Q gq
" In many terminal emulators the mouse works just
fine, thus enable it.
set mouse=a
" Switch syntax highlighting on,
when the terminal has colors
" Also switch on highlighting the last used
search pattern.
if &t_Co > 2 || has("gui_running")
syntax on
set
hlsearch
endif
" Only do this part when compiled with support for
autocommands.
if has("autocmd")
" Enable file type detection.
" Use
the default filetype settings, so that mail gets 'tw' set to 72,
" 'cindent'
is on in C files, etc.
" Also load indent files, to automatically do
language-dependent indenting.
filetype plugin indent on
" Put these in
an autocmd group, so that we can delete them easily.
augroup
vimrcEx
au!
" For all text files set 'textwidth' to 78
characters.
autocmd FileType text setlocal textwidth=78
" When editing
a file, always jump to the last known cursor position.
" Don't do it when the
position is invalid or when inside an event handler
" (happens when dropping
a file on gvim).
autocmd BufReadPost *
\ if line("'\"") > 0
&& line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif
augroup END
else
set autoindent " always set
autoindenting on
endif " has("autocmd")
" Convenient command to
see the difference between the current buffer and the
" file it was loaded
from, thus the changes you made.
command DiffOrig vert new | set bt=nofile |
r # | 0d_ | diffthis
\ | wincmd p | diffthis
"
///////////////////////////////////////////////////////////////
" common
options
if has("win32")
set encoding=utf-8
set termencoding=utf-8
set
fileencoding=chinese
set fileencodings=ucs-bom,utf-8,chinese
set
langmenu=zh_CN.utf-8
source $VIMRUNTIME/delmenu.vim
source
$VIMRUNTIME/menu.vim
language messages zh_cn.utf-8
language messages
zh_cn.utf-8
set guifont=Courier_New:h12:cANSI " 指定windows下的英文字體和大小
set
guifontwide=NSimSun:h11 " 指定windows下的中文字體和大小
else
set
fileencodings=utf8,gbk,big5
endif
set tabstop=4
set
shiftwidth=4
set mouse=a
set backupdir=~/tmp/vim/
set scroll=10
set
autoindent
set smartindent
set cindent
syntax enable
syntax
on
set fdm=indent
set foldlevel=100
set number
:map <F2>
:tabprevious<CR>
:map <F3> :tabnext<CR>
:imap <F2>
<ESC>:tabprevious<CR>
:imap <F3>
<ESC>:tabnext<CR>
" taglist and winmanager
integration
let Tlist_Use_SingleClick=1
let Tlist_Show_One_File=1
let
Tlist_Exit_OnlyWindow=1
let
g:winManagerWindowLayout='FileExplorer|TagList'
map wm
:WMToggle<cr>
" MiniBufferExplorer
let
g:miniBufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows =
1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1
let g:miniBufExplUseSingleClick = 1
"map <S-Tab> :bn<CR>
"map <C-Tab> :bp<CR>
" cscope options
set
cscopequickfix=s-,c-,d-,i-,t-,e-,g-
if has("cscope")
set
csprg=/usr/bin/cscope
"use both cscope and ctag for 'ctrl-]', ':ta', and
'vim -t'
set cscopetag
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
map <C-\>s
:cs find s <C-R>=expand("<cword>")<CR><CR>
:cw<CR>
map <C-\>g :cs find g
<C-R>=expand("<cword>")<CR><CR> :cw<CR>
map
<C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
:cw<CR>
map <C-\>t :cs find t
<C-R>=expand("<cword>")<CR><CR> :cw<CR>
map
<C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
:cw<CR>
map <C-\>f :cs find f
<C-R>=expand("<cfile>")<CR><CR> :cw<CR>
map
<C-\>i :cs find i
^<C-R>=expand("<cfile>")<CR>$<CR> :cw<CR>
map
<C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
:cw<CR>
" ctags options
set tags=./tags
" au BufWritePost
*.c,*.cpp,*.cc,*.h !cscope_ctags_cppfiles
" reproduce ctags and cscope.out
and reset cscope to vim.(ctags is automatically reseted)
map <F7>
:!ctags --extra=+q --fields=+Saim --java-kinds=+l --c++-kinds=+lpx
--c-kinds=+lpx -R . <CR><CR> :!find . -name "*.h" -o -name "*.c" -o
-name "*.cc" -o -name "*.cpp"> cscope.files <CR><CR> :!cscope
-bkq -i cscope.files<CR><CR> :cs
reset<CR><CR>
" c/cpp complete
imap <F8>
<C-X><C-O>
set completeopt=longest,menuone
let
OmniCpp_DefaultNamespaces = ["std"]
let OmniCpp_NamespaceSearch = 1
let
OmniCpp_MayCompleteDot = 1
let OmniCpp_MayCompleteArrow = 1
let
OmniCpp_MayCompleteScope = 1
let OmniCpp_ShowScopeInAbbr = 1
let
OmniCpp_ShowPrototypeInAbbr = 1
" color scheme
colorscheme
desert
" other options
map <F4> :cp<CR>
map <F5>
:cn<CR>
imap <F4> <ESC>:cp<CR>
imap <F5>
<ESC>:cn<CR>
map <F9>
:make<CR><CR><CR> :copen<CR>
map <F10>
:!./a.out<CR>
map <C-a> :A<CR>
imap <C-a>
<ESC>:A<CR>
map <Left> <CR> :bp<CR>
map
<Right> <CR> :bn<CR>
map <C-w>
:Rgrep<CR><CR><CR><CR>
imap <C-w>
<ESC>:Rgrep<CR><CR><CR><CR>
---------------------------------------------------------------------------------------------
(舊)六,、VIM配套工具集:
(一)用
cscope 查看源代碼
生成索引,記住Rbkq就行
cscope -Rbkq
-R:
在生成索引文件時(shí),搜索子目錄樹中的
代碼
-b: 只生成索引文件,不進(jìn)入 cscope 的界面
-k: 在生成索引文件時(shí),不搜索
/usr/includ
e 目錄
-q: 生成 cscope.in.out 和 cscope.po.out 文
件,加快 cscope
的索引速度
● cscope在Vim中的基本用法是 :cs + 子命令
:cs find {querytype}
{name}
● find 的子命令
s: Find this C symbol # 記法 s -
symbol,,查找的是symbol,,不是一般的text
g: Find this definition # g就記住是definition
d:
Find functions called by this function # d 是 called 后那個(gè)d
c: Find functions
calling this functio # c 是 called 前那個(gè)c
t: Find this text
string # t 是 text 的意思,就是 一般的 text 查找
e: Find this egrep
pattern # e 正則式了
f: Find this file
# f 是 file 的意思
i: Find files #including this file # i 是 include
的意思,,即查找 包含此頭文件的文件
當(dāng)然,,你可能會(huì)find很多,cs find
如果找到一個(gè),,則默認(rèn)定位到那個(gè)去,,如果找到多個(gè),則會(huì)列出來,,可能在本窗口列出(如果不設(shè)置在QuickFix窗口列出,,默認(rèn)就是這個(gè)樣子,可以看看),,也可能在QuickFix窗口列出,,那一般是設(shè)置在QuickFix這個(gè)單獨(dú)的窗口列出,見下邊.vimrc設(shè)置的這一行::set
cscopequickfix=s-,c-,d-,i-,t-,e-,g-
,,但默認(rèn)是不打開QuickFix窗口的,,所以要你自己用:cw或:copen打開后就看到結(jié)果了(關(guān)閉QuickFix可以用:cclose)。見下面的快捷鍵設(shè)置,,我默認(rèn)是打開的,,最后我加了一個(gè):cw<CR>.
不管在哪里列出,需要遍歷列出的項(xiàng),,則用鼠標(biāo)一個(gè)一個(gè)點(diǎn)擊,,或者用命令如下:
:cw
(或:copen)對(duì)make,cscope等,在最后一行提示你有多個(gè)選擇時(shí),你可以用:cw來打開QuickFix窗口,,用:cn定位到下一個(gè),,用:cp定位到上一個(gè),也可以在QuickFix窗口中用上下或鼠標(biāo)點(diǎn)擊操作,。當(dāng)然,,我為了方便,用快捷鍵設(shè)置了,,見下面,。設(shè)置到F7和F8上面了。
其他cs
的子命令:
在最后一行敲:cs你可以得到:所有的用法,,一目了然,,便于查找。簡(jiǎn)單說明如下:
上面的:cs
中的find子命令只是其中一個(gè),,其他的有如add常用于添加另一個(gè)cscope.out數(shù)據(jù)庫文件,,這樣你可以用很多個(gè),就是寫上路徑,。
show用于顯示現(xiàn)有的cscope連接,即你用add加成功的cscope.out數(shù)目,。
reset很有用,,當(dāng)你改完代碼后,需要重新生成cscope.out等文件
(重新生成cscope.out文件,,可以用:!外部命令,,這里應(yīng)該是 :!cscope -Rbkq), 這時(shí)為讓vim中的cscope數(shù)據(jù)庫刷新,,需要:cs
reset一下,。
:h
if_cscop.txt查看完整文檔
最后,為方便使用,,常為cscope的命令做map,,和vim相關(guān)的.vimrc的部分如下,完整的.vimrc查看另一篇博客,。
.vimrc中要寫的和cscope相關(guān)的:
"這表示cs的這些子命令都使用quickfix窗口,,-表示是更新quickfix窗口,而不是追加,。如果寫成
+,,如s+就表示是對(duì)quickfix窗口追加。如果沒出現(xiàn)在這里的命令,,默認(rèn)直接在當(dāng)前窗口下直接列出找到的所有項(xiàng),。
:set
cscopequickfix=s-,c-,d-,i-,t-,e-,g-
"下面的來自 :h
if_cscop.txt中的建議,不必太注意細(xì)節(jié),,只是看到里面已經(jīng)把當(dāng)前目錄下的cscope.out加進(jìn)去了,。
if
has("cscope")
set csprg=/usr/local/bin/cscope
set cscopetag
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
"做鍵的映射,,讓cscope更方便。其中
<C-R>=expand("<cword>")<CR> 是為了讓如 :cs find s
后添上當(dāng)前光標(biāo)處的word,,你可以自己敲這個(gè)試試.
nmap <C-\>s :cs find s
<C-R>=expand("<cword>")<CR><CR> :cw<CR>
nmap
<C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
:cw<CR>
nmap <C-\>c :cs find c
<C-R>=expand("<cword>")<CR><CR> :cw<CR>
nmap
<C-\>t :cs find t <C-R>=expand("<cword>")<CR><CR>
:cw<CR>
nmap <C-\>e :cs find e
<C-R>=expand("<cword>")<CR><CR> :cw<CR>
nmap
<C-\>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
:cw<CR>
nmap <C-\>i :cs find i
^<C-R>=expand("<cfile>")<CR>$<CR> :cw<CR>
nmap
<C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
:cw<CR>
"做鍵的映射,,能夠用F7和F8來切換QuickFix窗口中的項(xiàng)
map <F7>
:cp<CR>
map <F8> :cn<CR>
imap <F7>
<ESC>:cp<CR>
imap <F8> <ESC>:cn<CR>
"
這是為插入模式設(shè)置map, imap <F8> <ESC>:cn<CR>i
表明切換后仍為插入模式,,但是我不太喜歡,,有時(shí)會(huì)引起誤操作,所以一般不要后面那個(gè)i,。
最后,,這樣設(shè)置了配置文件后,就會(huì)有一些簡(jiǎn)單的用法可以用了:
ctrl-t
是本文件內(nèi)的跳轉(zhuǎn)到上次光標(biāo)位置
ctrl-o
是跨文件的跳轉(zhuǎn)(比如你上次打開一個(gè)文件,,又關(guān)閉了,,再打開一個(gè)新的,如果一直按這個(gè),,就會(huì)打開上次那個(gè)文件)
:ts tagname
查找所有的tagname符合的,,列出,供你選擇,,再跳轉(zhuǎn)
ctrl-] 在tagname上,, 等于 :cs find g
xxx
(二) 用ctags 查看源代碼:
由于ctags只是生成tags文件,不包含怎么在vim中找到某種特定的tag的命令,,比如函數(shù)原型怎么找,,定義怎么找等,它就是一個(gè)tags生成程序而以,。而VIM本身只提供純粹針對(duì)tags的查找(如列出所有相關(guān)tags,,調(diào)到第一個(gè)符合的tags...),即不識(shí)別類,,函數(shù)之類的,,所以VIM+ctags不能實(shí)現(xiàn)復(fù)雜查找。除非有其他插件支持,。且對(duì)c++支持不好,,比如從類成員的使用跳到c++類成員的定義處就不行,而只能用ts列出匹配項(xiàng),,讓你自己選,,而cscope可以。
所以最好用cscope,,它本身就在最后一行模式支持多種語言中特定tag類型(如類,,函數(shù))的查找,且可以map成快捷鍵。
下面為用法:
1.
ctags & tags:
tags是ctags生成的文件,,典型形式如下:
!_TAG_FILE_FORMAT 2
/extended format; --format=1 will not append ;" to
lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted,
2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert
/dhiebert@users./
!_TAG_PROGRAM_NAME Exuberant Ctags
//
!_TAG_PROGRAM_URL http://ctags. /official
site/
!_TAG_PROGRAM_VERSION 5.6 //
A main.cpp /^class
A{$/;" c file:
A::i main.cpp /^ int i;$/;" m
class:A file: access:private
A::ok main.cpp /^ ok()
{$/;" f class:A file: access:private signature:()
a
main.cpp /^ unsigned char a = 0x01 | 0x08;$/;" l
i
main.cpp /^ int i;$/;" m class:A file:
access:private
main main.cpp /^int main() {$/;" f
signature:()
ok main.cpp /^ ok() {$/;" f class:A
file: access:private
signature:()
很容易看懂意思吧,,每一行就是一個(gè)tag,后面跟出許多fields,。從形式上就這米簡(jiǎn)單,。
而cscope的不是這種tags形式,不太明白,,沒看,。
2.重要信息:
ctags
--list-kinds 打印出對(duì)每種語言支持識(shí)別的tags,比如C++支持類名,,函數(shù)定義,,函數(shù)原型...
ctags --list-languages
列出支持的語言
3.主要用法:
由于vim大約在7.0以后,支持了對(duì)你包含了的頭文件中的tag的下拉菜單補(bǔ)全,,比如你包含了一個(gè)系統(tǒng)頭文件或你自己的文件,,寫出一部分再按Ctrl-P,就可以有下拉的菜單,。當(dāng)然,,跳轉(zhuǎn)等復(fù)雜特性是不支持的。即便如此,,也不大需要對(duì)系統(tǒng)路徑下的文件進(jìn)行ctags掃描了,,下面所述,均針對(duì)你的程序文件:
(1)簡(jiǎn)單用法:
ctags
-R 在源代碼頂層目錄下執(zhí)行,,默認(rèn)配置適合大多數(shù)情況.(-R =
--recurse)
(2)復(fù)雜用法:
邏輯上這樣的:ctags自動(dòng)根據(jù)文件后綴判斷是什么語言的文件,并采取相應(yīng)的分析方法,,所以,,原則上將ctags
-R對(duì)任何程序文件都適用。
但是ctags到底處理語言中的哪些tags,,然后tags文件中到底包含哪些fields,,這個(gè)是需要詳細(xì)指定的,因?yàn)橐恍┠阆胍?,默認(rèn)沒有設(shè)置,,比如函數(shù)原型在c/c++中都默認(rèn)沒有去查找,所以要用--c++-kinds=+p
添加上函數(shù)原型,。下面 --c++-kinds=+lpx 和 --c-kinds=+lpx 只指定要加上lpx就行了,,是因?yàn)槟阌?ctags
--list-kinds,你會(huì)發(fā)現(xiàn),,它寫有哪些tags是默認(rèn)支持的,,而我發(fā)現(xiàn),就lpx沒有被默認(rèn)支持,所以我添加這三個(gè),。 而--fields=+Saim
是往tags文件中指定哪些field,,這個(gè)見man里有默認(rèn)顯示的field,這里是加上一些默認(rèn)不顯示的重要的,,記住是Saim就行了,!至于 --extra=+q
是為C++等增強(qiáng)特性:對(duì)是class的成員的tag,一律加上class名前綴,,即classname::tag,。
所以,這樣寫,,如果你想支持最多的話:
ctags
--extra=+q --fields=+Saim --c++-kinds=+lpx --c-kinds=+lpx -R Main.cpp
記法:3部分:
q Saim 和 lpx
我把這一堆(不包括-R)做了個(gè)alias為cpptags
(三) 為什么cscope比ctags強(qiáng)大 ───
因?yàn)閏tags僅僅用于生成tags文件,。
Cscope 是一個(gè)交互式的屏幕下使用的工具,用來幫助你:
*
無須在厚厚的程序清單中翻來翻去就可以認(rèn)識(shí)一個(gè) C 程序的工作原理,。
* 無須熟悉整個(gè)程序就可以知道清楚程序 bug 所要修改的代碼位置,。
*
檢查提議的改動(dòng) (如添加一個(gè)枚舉值) 可能會(huì)產(chǎn)生的效果。
* 驗(yàn)證所有的源文件都已經(jīng)作了需要的修改,;例如給某一個(gè)現(xiàn)存的函數(shù)添加一個(gè)參數(shù),。
*
在所有相關(guān)的源文件中對(duì)一個(gè)全局變量改名。
* 在所有相關(guān)的位置將一個(gè)常數(shù)改為一個(gè)預(yù)處理符號(hào),。
它被設(shè)計(jì)用來回答以下的問題:
*
什么地方用到了這個(gè)符號(hào),?
* 這是在什么地方定義的?
* 這個(gè)變量在哪里被賦值,?
* 這個(gè)全局符號(hào)的定義在哪里,?
*
這個(gè)函數(shù)在源文件中的哪個(gè)地方?
* 哪些函數(shù)調(diào)用了這個(gè)函數(shù),?
* 這個(gè)函數(shù)調(diào)用了哪些函數(shù),?
* 信息 "out of space"
從哪來?
* 這個(gè)源文件在整個(gè)目錄結(jié)構(gòu)中處于什么位置,?
* 哪些文件包含這個(gè)頭文件,?