vim 打造屬於自己的 IDE

一.ctags 安裝和配置

首先要說的是ctags是一個linux上很普遍的源碼分析工具, 可以將代碼中的函數變量等定義的位置記錄在一個名稱爲tags的文件. 類似於數據庫記錄功能. tags文件的產出最簡單的方法是在需要生成tags的工程項目的根目錄下執行ctags -R命令, 這會調用tags遞歸的掃描當前目錄以及所有子目錄中可以被tags識別的文件所以文件數據信息都會彙集到tags文件中.這裏總結一下幾個本人暫時知道的幾個需要注意的地方:

  ->ubuntu在默認系統環境中已經集成了ctags功能, 但這個ctags並不是完整的版本, 爲了保證vim可正常的使用tags建議安裝完整的ctags支持, ubuntu完整的ctags被重名爲exuberant-ctags但依然可以通過ctags索引到, 安裝命令如下:

  sudo apt-get install ctags

  ->如果你的vim有使用echofunc插件來顯示函數的參數定義, 那麼在使用ctags生產索引文件時需要使用如下附加參數:

  ctags -R --fields=+lS

  ->ctags默認生成的索引文件只包含了對C語言的語法分析, 如果你需要ctags支持對C++語法分析. 需要使用下面的命令:

  ctags -R --c++-kinds=+p --fields=+iaS --extra=+q

       ->如果同時支持上面兩個使用場景,需要使用下面的命令:

       ctags -R --c++-kinds=+p --fields=+liaS --extra=+q

  ->如果你在C語言編寫的代碼中使用上面提到的C++命令生成tags, 那麼你將驚訝的發現, 當你希望通過ctags跳轉到光標下函數定義的地方的時候, vim總是跳轉到這個函數定義的地方, 原因是ctags的C++命令增加了額外的語法分析以便支持C++更加複雜的語法結構, 這種額外的語法分析用在C語言中的時候就會出現跳轉默認定位到函數聲明的地方.

  ->ctags默認是支持C和C++的由於本人暫時沒有做過其他語言的開發工作, 所以不清楚ctags是否支持其他編程語言.

  ->請不要每次生成tags的時候都使用上面的命令, 包括以後其他的很多功能的實現都是如此, 命令是實現一個功能的原型, 如果僅僅使用命令在類unix(windows下面也是如此)的操作系統上實現常用的操作和功能, 那麼你的操作將會變得很低效. 個人認爲vim的使用也有這個規律, 最普遍的操作最好不要使用長長的命令來實現. 取而代之的方法是設置快捷鍵和命令的簡寫映射.

二. ctags 在 vim中的使用

  vim配置tags使用的過程是, 先在終端中生成一個項目的tags文件, 再在vimrc中告訴vim哪裏去找這個tags. 假如我們有一個項目在/home/boddy/hello/下面, 並且這個目錄下已經生成tags文件.那麼只要在vimrc文件中添加如下語句就可以讓vim在每次啓動的時候自動找到這tags了:

 set tags+=/home/boddy/holle/tags

 如果你有多個tags需要使用,可以重複上面的語句, 也可以在同一個語句中加入多個路徑,每個路徑用","隔開.

這種方法是我最初使用tags的的方式, 缺點顯而易見, 每當我們開始新的項目的時候,不得不重新修改set tags後面的路徑, 雖然這樣的修改並不麻煩, 也不需要經常操作. 但不免還是讓人覺得太死板不智能.

  爲了讓vim對tags的支持更加自動話, 首先想到的方法是在vimrc中添加 settags+=./tags語句, 這樣當前目錄下的tags就不需要我們手動添加了.但我們不可能永遠在項目的根目錄操作. 如果在項目的子目錄裏操作, 這個方法將會失效. 事實上, 任何一個項目文件夾都有一個顯著的特點: 任何子目錄遞歸向上都可以到達項目的根目錄. 這個特點將會在下面的實踐中大顯身手, 讓我們從各種和項目整體相關的操作中解脫出來. 這包括ctags cscope lookupfile等相關索引文件的自動添加和隨時更新. 在項目任意子目錄下的任意時刻對項目的自動make和make clean等. 這些最頻繁操作要麼是自動完成的要麼是通過vimrc的map功能映射到不同的快捷鍵上, 這會讓我們的vim具有所以IDE所具有的便捷性的同時保持了vim在編碼方面無比的高校性和在功能定製方便的無比的可定製性. 我想這就是我爲什麼寧願選擇折騰vim而沒有使用成熟的IDE的原因.

  上面提到工程項目的目錄遞歸特性, 實際上, 我們需要使用一個tags最典型的需求是希望在一個項目中快速的找到函數,變量,宏等定義的地方. 這些查找大多是在項目文件夾內完成. 因此, 只要我們能上vim實現對當前所在目錄的遞歸查找功能, 這個需求就會滿足. 只要項目的根目錄下存在tags文件, 任何時候任在任何一個項目的子目錄下使用vim都可以正確的找到這個tags, 同時如果我們的電腦中存在多個項目, 當我們切換到另一個項目的子目錄的時候, vim遞歸查找到永遠是當前項目根目錄下面的tags(前提是tags存在於項目根目錄), 無意間就實現tags的自動切換功能. 

  實現vim對tags的自動遞歸查找其實很簡單, 因爲vim已經實現了這個功能, 只是默認沒有開啓. 在vimrc添加下面兩行配置, 就會是見證奇蹟的時刻:

  set autochdir
  set tags=tags;

  set autochdir表示自動切換目錄的意思, set tags=tags;表示自動查找, 這兩句同時設置vim即可實現遞歸的tags查找, 注意: set tags=tags;這一句的最後有一個分號, 這個分號是不能省略的. vim的配置文件使用的是vim自己的腳步語言. 這裏是少數幾個在行尾需要使用分號的地方之一.

  最後需要說明的一點: ctags在默認的命令下生成的tags中使用的是相對路徑的存放所有查找結果, 這在多數情況下是一個優點, 因爲相對路徑不依賴於項目的根目錄所在位置. 這樣在整個項目轉移到別的位置的時候, 相對路徑的tags依然可以正常的實現跳轉. 不過相對路徑的tags並不是沒有缺點, 如果你的vim中使用了FuzzyFinder來作爲查找項目文件的工具, 你將驚訝的發現如果你在項目根目錄的子目錄下執行項目文件查找,在找到了想要的文件並最後回車跳轉的時候如果tags使用的是相對路徑, 這一步將會失敗, 因爲FuzzyFinder無法正確的通過當前的目錄(不是項目根目錄)加上tags中的相對路徑計算出正確的文件位置. 解決的辦法是在ctags生產tags文件的時候使用絕對路徑, 使用方法是在ctags -R 的命令後面添加項目根目錄的絕對路徑, 如: ctags -R /home/boddy/hello/ , 使用絕對路徑可以保證tags在任何調用他的工具中正確的找到文件位置. 唯一的缺點是如果項目移動了, tags必需重新生成, 鑑於我們的項目在自己的電腦中移動的需求很小的同時重新生成一tags的時間也就是幾秒鐘的事情(只要不是超級大的項目,tagseh生成還是很快的), 我個人選擇了在任何時候使用ctags都使用絕對路徑, 當然這個功能是在vim中通過參數自動實現的, 本文的最後將會提到.

三. cscope的安裝和配置

        sudo apt-get install cscope

使用ctags生成tags類似,通過下述命令可以生成cscope.out[2]:

    在當前目錄中生成cscope.out:

[plain] view plain copy
  1. cscope -Rb  

(2) 添加額外的目錄

指定源碼絕對路徑,查找時不受當前工作路徑的限制:

[plain] view plain copy
  1. cscope -Rb -s absoluteDir  

    例如在進行Linux驅動開發的時候,將absoluteDir取爲Linux源碼所在的目錄,然後在驅動項目目錄執行上述命令(不是進入Linux源碼中哦,而是自己在Linux源碼之外所創建的目錄)。此時,在進行驅動開發的時候,就可以利用cscope的查找功能了, 而不必將當前目錄切換到Linux源碼目錄中。

(3)添加路徑前綴

    通過第上述步驟(2)雖然可以達到搜索不受工作路徑的影響,但是會有一個副作用:同一個文件會有兩個重複的路徑,一個相對路徑,一個絕對路徑。因此,在查找的過程中,會出現重複的結果。

    爲了避免上述副作用,最好是使用下述命令代替上述第(2)步的命令,同樣可以達同樣的目的,並避免了副作用:

  1. cscope -Rbqkv -P pwd  

    -P,表示爲搜索路徑添加前綴, pwd是獲取當前工作路徑的命令。

3.2 添加目錄/庫文件

(1)手動方式    

打開vim之後,可以通過下述命名添加目錄

[plain] view plain copy
  1. :cs add directory  
或者
[plain] view plain copy
  1. :cscope add directory  

(2)自動方式一    

也可以將下面語句添加到vim的配置文件.vimrc

[plain] view plain copy
  1. if filereadable("cscope.out")  
  2.     cs add cscope.out  
  3. elseif $CSCOPE_DB  != ""  
  4.     cs add $CSCOPE_DB  
  5. endif      

    這樣子就會在打開vim的時候自動加載當前目錄下車cscope.out文件。

(3)自動方式二

autoload_cscope.vim插件更方便,它會先在當前目錄查找cscope.out,有則加載,否則進入其父目錄查找,直到找到可用的cscope.out爲止。

四、cscope 的使用

3.3 find命令

Cscope的功能通過它的子命令find來實現。

[plain] view plain copy
  1. :cs find c|d|e|g|f|i|s|t name  
    其中各個參數意義如下[5]:
[plain] view plain copy
  1. s -- symbol:find all references to the token under cursor  
  2. g -- global:find global definition(s) of the token under cursor  
  3. c -- calls:find all calls to the function name under cursor  
  4. t -- text:find all instances of the text under cursor  
  5. e -- egrep:egrep search for the word under cursor  
  6. f -- file:open the filename under cursor  
  7. i -- includes:find files that include the file name under cursor  
  8. d -- called:find functions that function under cursor calls  
3.4 快捷鍵映射

    爲了便於查找,根據參考資料[4][5]的提示,可以在.vimrc中設置上述各命令的快捷映射:

[plain] view plain copy
  1. nmap <S-s> :cs find s <C-R>=expand("<cword>")<CR><CR>  
  2. nmap <C-g> :cs find g <C-R>=expand("<cword>")<CR><CR>  
  3. nmap <S-c> :cs find c <C-R>=expand("<cword>")<CR><CR>  
  4. nmap <S-t> :cs find t <C-R>=expand("<cword>")<CR><CR>  
  5. nmap <S-e> :cs find e <C-R>=expand("<cword>")<CR><CR>  
  6. nmap <S-f> :cs find f <C-R>=expand("<cword>")<CR><CR>  
  7. nmap <S-i> :cs find i ^<C-R>=expand("<cword>")<CR>$<CR>  
  8. nmap <S-d> :cs find d <C-R>=expand("<cword>")<CR><CR>  

    使用時,將光標停留在要查找的對象上,按下Ctrl + g,將會查找該對象的定義(這裏使用Ctrl是爲了避免和vim的原有快捷方式衝突);其它的快捷方式使用如Shift+ s/c/t/e/f/i/d。

五,在coding過程中,有了變量或函數的自動彈出功能,可以極大的提高編碼的效率和準確率,這裏介紹的AutoComplPop和OmniCppComplete腳本插件就是實現這樣一個功能。

1. 代碼(普通變量函數)的自動彈出 AutoComplPop

下載:http://www.vim.org/scripts/script.php?script_id=1879 

        安裝:

               先解壓:unzip vim-autocomplpop.zip

              同其他腳本插件的安裝方法一致,將解壓後的文件拷貝到~/.vim/ 下的相應目錄裏:

                     autoload/*    ->    ~/.vim/autoload/

                     doc/*    ->    ~/.vim/doc/

                     plugin/*    ->    ~/.vim/plugin/

       使用:

              重新打開vim即可使用。添加help文件:helptags ~/.vim/doc/即可(打開幫助文件:h(elp) autocomplpop)

       效果圖:


2. c/c++代碼(類的 . , ->, :: 操作符)的自動補全 OmniCppComplete

       下載:http://www.vim.org/scripts/script.php?script_id=1520

       安裝:

              先解壓:unzip omnicppcomplete-0.41.zip

              同其他腳本插件的安裝方法一致,將解壓後的文件拷貝到~/.vim/ 下的相應目錄裏:

                     autoload/*    ->    ~/.vim/autoload/

                     doc/*    ->    ~/.vim/doc/

                     after/*    ->    ~/.vim/after/

       使用:

              重新打開vim,添加help文件:helptags ~/.vim/doc/(打開幫助文件:h(elp) omnicppcomplete),但其功能的展現還需要一下操作和設置:

              omnicppcomplete腳本插件的基本設置,在~/.vimrc中添加(我的喜好設置):

                     set completeopt=menu,menuone  
                     let OmniCpp_MayCompleteDot=1    “  打開  . 操作符
                     let OmniCpp_MayCompleteArrow=1  "打開 -> 操作符
                     let OmniCpp_MayCompleteScope=1  ”打開 :: 操作符
                     let OmniCpp_NamespaceSearch=1   “打開命名空間
                     let OmniCpp_GlobalScopeSearch=1  
                     let OmniCpp_DefaultNamespace=["std"]  
                     let OmniCpp_ShowPrototypeInAbbr=1  “打開顯示函數原型
                     let OmniCpp_SelectFirstItem = 2”自動彈出時自動跳至第一個

              要生成專用於c/c++的ctags文件,並引導vim找到改tags文件:

              tags文件生成命令(通常位於代碼項目的最上層目錄下執行)[admin@local]$ ctags -R --c++-kinds=+p --fields=+iaS --extra=+q

              引導omnicppcomplete找到tags文件:

                     (1)在vim中設置:set tags+=/home/project/project_1/tags 。該方法不方便,每次使用都要set一下

                     (2)在~/.vimrc中添加常用的路徑tags:

                            set tags+=/home/project/project_1/tags

                            set tags+=/home/project/project_2/tags

              這樣,每次打開vim便會自動尋找以上設置的tags文件。另外,可以通過vim中:set tags來查看已設置的tags文件路徑。

       效果圖:

 

六、在vim中加入echofunc這個可以自動提示函數原型的插件,最先版可以通過以下鏈接下載:

http://www.vim.org/scripts/script.php?script_id=1735

該插件主要是解決omnicppcomplete不能補全函數的問題,基本上也不用配置,主要是在.vimrc中定義兩個快捷鍵來切換函數的不同定義。

安裝:把下載下來的 echofunc.vim 放到 $HOME/.vim/plugin 目錄下。
幫助:請看 echofunc.vim 的開頭部分。

插件 echofunc 依賴於另一個插件 ctags 。創建 tags 文件時使用以下命令:

$ ctags -R --fields=+lS
  1. let g:EchoFuncKeyNext='<S-n>'  
  2. let g:EchoFuncKeyPrev='<S-p>'  





發佈了8 篇原創文章 · 獲贊 32 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章