ctags的使用及相關引數介紹

2021-06-16 22:50:55 字數 4245 閱讀 1752

因為學習使用vim,遇到ctags這樣乙個東東,花了一天時間大致搞清楚了一點,記下來,和大家分享。我寫的匆忙,大家也就隨便看看好了。希望有用。

一.        ctags是幹什麼的

二.        ctags可以識別哪些語言,是如何識別的

ctags識別很多語言,可以用如下命令來檢視:

ctags --list-languages

還可以識別自定義語言,具體沒研究過。

ctags是可以根據檔案的副檔名以及檔名的形式來確定該檔案中是何種語言,從而使用正確的分析器。可以使用如下命令來檢視預設哪些副檔名對應哪些語言:

ctags --list-maps

還可以指定ctags用特定語言的分析器來分析某種副檔名的檔案或者名字符合特定模式的檔案。例如如下命令告知ctags,以inl為副檔名的檔案是c++檔案。

ctags --langmap=c++:+.inl –r

並不十分清楚ctags使用何種技術來解析內容,估計包括正規表示式、詞法分析、語法分析等等。但ctags不是編譯器也不是預處理器,它的解析能力是有限的。例如它雖然可以識別巨集定義,但對於使用了巨集的語句的識別還是有缺陷的,在一些稍微正規點的**(例如ace的庫或vc的標頭檔案等)中的某些常規的巨集使用方式會導致ctags無法識別,或者識別錯誤,從而使得ctags沒有記錄user想記錄的內容,或者記錄下的資訊不準確。另一方面ctags也有聰明的一面,例如在cpp檔案中掃瞄到static的全域性變數時,ctags會記錄這個變數,而且還會標明說這個變數是侷限於本檔案的,同樣的定義,如果放在h檔案中,ctags則不會標明說這個變數是侷限於本檔案的,因為ctags認為h檔案是標頭檔案的一種,會被其他檔案include,所以在其他檔案中可能會用到該h檔案裡定義的這個全域性變數。

三.        ctags可以識別和記錄哪些語法元素

可以用如下命令檢視ctags可以識別的語法元素:

ctags --list-kinds

或者單獨檢視可以識別的c++的語法元素

ctags --list-kinds=c++

ctags識別很多元素,但未必全都記錄,例如「函式宣告」這一語法元素預設是不記錄的,可以控制ctags記錄的語法元素的種類。如下命令要求ctags記錄c++檔案中的函式宣告和各種外部和前向宣告:

ctags -r --c++-kinds=+px

四.        ctags是怎麼記錄的

不管一次掃瞄多少檔案,一條ctags命令把記錄的內容都記到乙個檔案裡去,預設是當前目錄的tags檔案,當然這是可以更改的。

每個語法元素對應檔案裡的一行,學名叫tag entry。

1)             開頭是tag的名字,其實也就是語法元素的名字,例如記錄的是函式的話則tag名就是函式名,記錄的是類的話,tag名就是類名。

2)             接下來是乙個tab。

3)             接下來是語法元素所在的檔名。

4)             又是乙個tab。

5)             一條「命令」。這個要解釋一下意義:ctags所記錄的內容的乙個功能就是要幫助像vi這樣的編輯器快速定位到語法元素所在的檔案中去。前面已經記錄了語法元素所在的檔案,這條命令的功能就是一旦在vi中開啟語法元素所在的檔案,並且執行了該「命令」後,vi的游標就能定位到語法元素在檔案中的具體位置。所以該「命令」的內容一般分兩種,一種是乙個正規表示式的搜尋命令,一種是第幾行的指向命令。預設讓ctags在記錄時自行選擇命令的種類,選擇的依據不詳,可以通過命令列引數來強制ctags使用某種命令,這裡就不多談了。

6)             對於本tag entry(簡稱tag)所對應的語法元素的描述,例如語法元素的型別等。具體內容和語法元素的種類密切相關。顯示哪些描述,顯示的格式等都是可以在命令列指定的。例如如下命令要求描述資訊中要包含:a表示如果語法元素的類的成員的話,要標明其access(即是public的還是private的);i表示如果有繼承,標明父類;k表示顯示語法元素的型別的全稱;s表示如果是函式,標明函式的signature;z表示在顯示語法元素的型別是使用kind:type的格式。

ctags -r --fields=+aiksz

ctags除了記錄上述的各種內容之外,還可以在tags檔案中記錄本次掃瞄的各個檔案,乙個檔名對應乙個tag entry。預設是不記錄的,要強制記錄要是使用如下命令:

ctags –r --extra=+f

還可以強制要求ctags做這樣一件事情——如果某個語法元素是類的乙個成員,當然ctags缺省會給其記錄乙個tag entry(說白了就是在tags檔案裡寫一行),可以要求ctags對同乙個語法元素再記一行。舉乙個例子來說明:假設語法元素是乙個成員函式,ctags預設記錄的tag entry中的tag的名字就是該函式的名字(不包括類名作為字首),而我們強制要求ctags多記的那個tag entry的tag的名字是包含了類明作為字首的函式的全路徑名。這樣做有什麼好處見下文分析。強制ctags給類的成員函式多記一行的命令為:

ctags -r --extra=+q

五.        vi大概是怎樣使用ctags生成的tags檔案的

估計vi是這樣使用tags檔案的:我們使用vi來定位某個tag時,vi根據我們輸入的tag的名字在tags檔案中一行行查詢,判斷每一行tag entry的tag名字(即每行的開頭)是否和使用者給出的相同,如果相同就認為找到一條記錄,最後vi顯示所有找到的記錄,或者根據這些記錄直接跳轉到對應檔案的特定位置。

考慮到ctags記錄的內容和方式,出現同名的tag entry是很常見的現象,例如函式宣告和函式定義的tag名字是一樣的,過載函式的tag名字是一樣的等等。vi只是使用tag名字來搜尋,還沒智慧型到可以根據函式的signature來選擇相應的tag entry。vi只能簡單的顯示tag entry的內容給user,讓user自行選擇。

ctags在記錄成員函式時預設是把函式的名字(僅僅是函式的名字,不帶任何類名和namespace作為字首)作為tag的名字的,這樣就導致很多不同類但同名的函式所對應的tag entry的名字都是一樣的,這樣user在vi中使用函式名來定位時就會出現暴多選擇,挑選起來十分麻煩。user可能會想在vi中用函式的全路徑名來進行定位,但這樣做會失敗,因為tags檔案中沒有對應名字的tag entry。要滿足使用者的這種心思,就要求ctags在記錄時針對類的成員多記錄一條tag entry,該tag entry和已有的tag entry的內容都相同,除了tag的名字不同,該tag entry的名字是類的成員的全路徑名(包括了命名空間和類名)。這就解釋了ctags的--extra=+q這樣一條命令列選項(見四)。

六.        我的一條ctags命令

ctags -r --languages=c++ --langmap=c++:+.inl -h +.inl --c++-kinds=+px --fields=+aiksz --extra=+q --exclude=lex.yy.cc --exclude=copy_lex.yy.cc

命令太長了,折成兩行了,可以考慮把命令的各個引數寫到檔案裡去了(具體做法就不談了)。

1.-r

表示掃瞄當前目錄及所有子目錄(遞迴向下)中的原始檔。並不是所有檔案ctags都會掃瞄,如果使用者沒有特別指明,則ctags根據檔案的副檔名來決定是否要掃瞄該檔案——如果ctags可以根據檔案的副檔名可以判斷出該檔案所使用的語言,則ctags會掃瞄該檔案。

2.--languages=c++

只掃瞄檔案內容判定為c++的檔案——即ctags觀察副檔名,如果副檔名對應c++,則掃瞄該檔案。反之如果某個檔案叫aaa.py(python檔案),則該檔案不會被掃瞄。

3.--langmap=c++:+.inl

告知ctags,以inl為副檔名的檔案是c++語言寫的,在加之上述2中的選項,即要求ctags以c++語法掃瞄以inl為副檔名的檔案。

4.-h +.inl

告知ctags,把以inl為副檔名的檔案看作是標頭檔案的一種(inl檔案中放的是inline函式的定義,本來就是為了被include的)。這樣ctags在掃瞄inl檔案時,就算裡面有static的全域性變數,ctags在記錄時也不會標明說該變數是侷限於本檔案的(見第一節描述)。

5.--c++-kinds=+px

記錄型別為函式宣告和前向宣告的語法元素(見第三節)。

6.--fields=+aiksz

控制記錄的內容(見第四節)。

7.--extra=+q

讓ctags額外記錄一些東西(見第

四、五節)。

8.--exclude=lex.yy.cc --exclude=copy_lex.yy.cc

告知ctags不要掃瞄名字是這樣的檔案。還可以控制ctags不要掃瞄指定目錄,這裡就不細說了。

exuberant ctags附帶的幫助文件(ctags.html)。

ctags的使用及相關引數介紹

因為學習使用vim,遇到ctags這樣乙個東東,花了一天時間大致搞清楚了一點,記下來,和大家分享。我寫的匆忙,大家也就隨便看看好了。希望有用。一 ctags 是幹什麼的 二 ctags 可以識別哪些語言,是如何識別的 ctags 識別很多語言,可以用如下命令來檢視 ctags list langua...

vim及ctags的使用

0.vim的配置檔案 在使用者目錄下 新建檔案.vimrc,儲存即可生效。如果想所有使用者生效,請修改 etc vimrc 建議先cp乙份 1.vim hello.c 在當前目錄下建立hello.c檔案,並進入vim的一般模式,一般模式下不能插入,可以複製 貼上 刪除。按下i a或o按鍵,進入插入模...

ctags安裝及使用

使用及問題 sudo apt get install ctags 沒搞明白ctags和ctags exuberant的區別,之前12.04和14.04版本的ubuntu使用的是ctags,現在20.04ctags就有問題了,只能使用ctags exuberant,不過效果還是一樣的。ctags檢視版...