本節(jié)所用命令的幫助入口:
:help 'tags'
:help :tag
:help :tags
:help CTRL-]
:help CTRL-T
:help vimgrep
:help cw
:help pattern
盡管相關(guān)的文章已經(jīng)很多了,但tag文件實(shí)在是太有用了,所以還是啰嗦一次。
Tag文件(標(biāo)簽文件)無(wú)疑是開(kāi)發(fā)人員的利器之一,有了tag文件的協(xié)助,你可以在vim查看函數(shù)調(diào)用關(guān)系,類、結(jié)構(gòu)、宏等的定義,可以在任意標(biāo)簽中跳轉(zhuǎn)、返回……相信使用過(guò)Source Insight的人對(duì)這些功能并不陌生,而在vim中,此功能的實(shí)現(xiàn)依賴于tag文件。
對(duì)于程序來(lái)說(shuō),Tag文件中保存了諸如函數(shù)、類、結(jié)構(gòu)、宏等的名字,它們所處的文件,以及如何通過(guò)Ex命令跳轉(zhuǎn)到這些標(biāo)簽。它是一個(gè)純文本文件,因此你可以手工的編輯它,也可以使用腳本對(duì)其進(jìn)行操作。
通常我們使用名為ctags的程序來(lái)生成這樣的tag文件。vim能直接使用ctags程序所生成的tag文件。在UNIX系統(tǒng)下的ctags功能比較少,所以一般我們使用ExuberantCtags(在大多數(shù)Linux系統(tǒng)上,它是缺省的ctags程序),它能夠支持多達(dá)33種程序語(yǔ)言,足以滿足我們開(kāi)發(fā)的需要了。這里是它的中文手冊(cè)。如果你的系統(tǒng)上未安裝此程序,請(qǐng)到http://ctags.sourceforge.net下載。
emacs則使用etags來(lái)生成tag文件,如果希望vim也能支持etags的tag文件格式,需要編譯vim時(shí)加入”+emacs_tags“選項(xiàng)。在這篇文章介紹了編譯vim的方法。
Tag文件需要遵循一定的格式,由Exuberant Ctags生成的tag文件,缺省是如下格式:
{tagname} {TAB} {tagfile} {TAB} {tagaddress} {term} {field} ..
在{tagname}、{tagfile}和{tagaddress}之間,采用制表符(TAB符,即C語(yǔ)言中的”\t”)分隔,也就是說(shuō){tagname}、{tagfile}的內(nèi)容中不能包含制表符。
Tag文件的開(kāi)頭可以包含以”!_TAG_”開(kāi)頭的行,用來(lái)在tag文件中加入其它信息。vim能夠識(shí)別兩種這樣的標(biāo)記,經(jīng)常用到的是”_TAG_FILE_SORTED”標(biāo)記,例如:
!_TAG_FILE_SORTED<Tab>1<Tab>{anything}
上面這個(gè)標(biāo)記說(shuō)明tag文件是經(jīng)過(guò)排序的,并且排序時(shí)區(qū)分了大小寫(xiě),對(duì)排序的tag,vim會(huì)使用二分法來(lái)進(jìn)行查找,大大加快了查找速度;如果值為0,則表示tag文件未經(jīng)排序;如果值為2,則表示tag文件是忽略大小寫(xiě)排序的。
之所以在這里介紹tag文件的格式,是因?yàn)槲覀冊(cè)诤竺嫣岬降?a class="link" target="_blank">lookupfile插件中,會(huì)自己生成tag文件。
雖然ctags有為數(shù)眾多的選項(xiàng),但通常我們所使用的非常簡(jiǎn)單。還是以vim 7.0的代碼為例,我們執(zhí)行:
cd ~/src/vim70
ctags –R src
上面這條命令會(huì)在~/src/vim70/目錄下生成一個(gè)名為tags的文件,這個(gè)文件中包含~/src/vim70/src/目錄下所有.c、.h文件中的標(biāo)簽。它一個(gè)文本文件,你可以用vim打開(kāi)它看一下。此文件缺省按區(qū)分字母大小寫(xiě)排序,所以直接可以被vim使用。
現(xiàn)在我們進(jìn)入vim,執(zhí)行下面的命令:
:cd ~/src/vim70 "切換當(dāng)前目錄為~/src/vim70
:set tags=tags "設(shè)置tags選項(xiàng)為當(dāng)前目錄下的tags文件
現(xiàn)在,我們?cè)O(shè)置好了tags選項(xiàng),接下來(lái)我們使用它:
:tag VimMain
你會(huì)看到vim打開(kāi)了src/main.c文件,并把光標(biāo)定位到第167行VimMain上。
我們知道,一般主程序的函數(shù)名為main,如果你嘗試下面的命令:
:tag main
# pri kind tag file
1 F f main src/xxd/xxd.c
main(argc, argv)
2 FS d main src/if_python.c
46
Choice number (<Enter> cancels):
這里并沒(méi)有src/main.c文件,怎么回事呢?這是因?yàn)閏tags并不是編譯器,它在處理編譯預(yù)處理指令受到局限,因此并沒(méi)有生成src/main.c中main()函數(shù)的標(biāo)簽。你可以在生成tag文件時(shí)給ctags指定參數(shù)來(lái)解決這個(gè)問(wèn)題。見(jiàn)ctags手冊(cè)。
或者你可以用”:grep“或”:vimgrep“來(lái)查找main(這篇文章講解grep及vimgrep的用法):
:cd ~/src/vim70
:vimgrep /\<main\>/ src/*.c
:cw
這時(shí)下面的quickfix窗口將顯示出來(lái),在quickfix窗口中找到我們想跳轉(zhuǎn)的位置(本例中是src/main.c),按回車,就可以跳到對(duì)應(yīng)的位置了。
如果你只記得部分的標(biāo)簽名,那么可以使用”tag“命令的搜索模式,你可以輸入一個(gè)vim正則表達(dá)式來(lái)表示你所查找的名字,如:
:tag /\C\<\k\+ain\>
# pri kind tag file
1 F f VimMain src/main.c
VimMain
2 F d bindtextdomain src/vim.h
483
3 F d bindtextdomain src/vim.h
502
4 F d bindtextdomain src/vim.h
504
5 F f main src/xxd/xxd.c
main(argc, argv)
6 F d textdomain src/vim.h
488
7 F d textdomain src/vim.h
510
8 F d textdomain src/vim.h
512
9 FS d bindtextdomain src/gui_gtk.c
54
10 FS d bindtextdomain src/gui_gtk_x11.c
37
11 FS f cmdsrv_main src/main.c
cmdsrv_main(argc, argv, serverName_arg, serverStr)
12 FS d main src/if_python.c
46
13 FS d textdomain src/gui_gtk.c
51
14 FS d textdomain src/gui_gtk_x11.c
34
Choice number (<Enter> cancels):
這表示我想查找一個(gè)以一個(gè)或多個(gè)keyword開(kāi)始的標(biāo)簽,此標(biāo)簽以ain做為結(jié)尾,在查找時(shí)區(qū)分大小寫(xiě)。要讀懂這個(gè)正則表達(dá)式,請(qǐng)”:help pattern“。
vim會(huì)保存一個(gè)跳轉(zhuǎn)的標(biāo)簽棧,以允許你在跳轉(zhuǎn)到一個(gè)標(biāo)簽后,再跳回來(lái),可以使用”:tags“命令查找你處于標(biāo)簽棧的哪個(gè)位置。
我們經(jīng)常用到的tag跳轉(zhuǎn)命令見(jiàn)下(一般只需要知道CTRL-]和CTRL-T就可以了):
:tag {ident} "跳轉(zhuǎn)到指定的標(biāo)簽
:tags "顯示標(biāo)簽棧
CTRL-] "跳轉(zhuǎn)到當(dāng)前光標(biāo)下的標(biāo)簽
CTRL-T "跳到標(biāo)簽棧中較早的標(biāo)簽
如果想了解更多命令,可以”:help 29.1“(強(qiáng)烈建議程序員完整的閱讀usr_29.txt和usr_30.txt)。
如果想更深入了解tag命令和相關(guān)知識(shí),可以”:help tagsrch“。
聯(lián)系客服