1. 程式人生 > >vim中的殺手級外掛: YouCompleteMe

vim中的殺手級外掛: YouCompleteMe

寫在前面的話:
我現在覺得 其實如果能用圖形介面可以找到相應的IDE 比如 codelite, qtcreator, eclipse...
只有在命令列模式下才會用vim. 不要因為配置環境而忽略了寫程式碼的樂趣。
畢竟 這些只是一個工具而已,自己熟悉一個東西工具勝過所有的工具會一點點。

Vim程式碼補全現狀

在漫長的Vim發展歷史中,程式碼補全一直是比較被忽視的環節,相比眾多IDE,vim本身的程式碼提示功能包括其眾多補全外掛顯得無比簡陋, 這是因為vim的先天不足,它是文字編譯器,不能理解程式語意。引用王垠的一段文字:

“文字編輯器”這種東西一般都不真正的理解程式語言。很多 Emacs 和 vi 的使用者以為用 etags 和 ctags 這樣的工具就能讓他們“跳轉到定義”,然而這些 tags 工具其實只是對程式的“文字”做一些愚蠢的正則表示式匹配。它們根本沒有對程式進行 parse,所以其實只是在進行一些“瞎猜”。簡單的函式定義它們也許能猜對位置,但是對於有重名的定義,或者區域性變數的時候,它們就力不從心了。

《編輯器與IDE》

或許對於python,PHP等動態語言,因為本身的語言特性和豐富的工具支援,也能做到不錯的補全效果,但對於C/C++程式碼的補全, AutoComplPop, omnicppcomplete, neocomplcache等外掛的確都是在“瞎猜”。

還有一個原因是沒有大牛來做這些功能。在漫長的Vim或emacs歷史中,它都是掌握在少數精英程式設計師手裡,擴充套件它都需要一定的專業知識,我輩普通程式設計師只是在使用它。而程式碼補全並不是大牛們的必須,我曾經和一個瑞典的PSE做Pair Programming, 只使用emacs和grep等linux命令,他就可以在整個工程裡穿梭自如,常用庫的呼叫瞭然於心,程式碼結構清晰,幾乎沒有語法和拼寫錯誤。估計他看到我花裡胡哨的vim, 還用程式碼提示,心裡也是一陣鄙視吧。所以儘管大牛們讓emacs可以煮咖啡,vim可以發微博,但是vim和emacs的程式碼提示一如既往的爛了二三十年。

在Apply公司支援的LLVM/clang誕生後,事情迎來了轉機。clang強大語義分析能力,為C/C++/Object-C原始碼級別的分析和轉化提供了可能,基於clang的語意補全外掛開始在vim和emacs上出現。

YouCompleteMe

YouCompleteMe是一個比較新Vim程式碼補全外掛,可以基於clang為C/C++程式碼提供程式碼提示。它安裝配置簡單,Bug 很少。 對C/C++來說youcompleteme現在應該是最好選擇,藉助clang的強大功能,補全效率和準確性極高,而且可以模糊匹配(見下面的demo)。不管你的C++程式碼用什麼怪異的寫法,只要能編譯通過,都能補全,即使是C++11的lambda和auto都沒有障礙,比codeblock這些根據tag index補全的IDE都要強大。

YCM的安裝配置

YCM需要最新版本Vim(7.3.584)的支援,從程式碼編譯Vim的方法看這裡
使用Vundle安裝 youcompleteme後,需要先編譯才能使用。

1
2
cd ~/.vim/bundle/YouCompleteMe
./install.sh --clang-completer

語意補全要正確工作,需要配置好.ycm_extra_conf.py檔案,模板在這裡。可以把這個檔案放在專案的根目錄下,開啟專案檔案時,YCM會迴圈向上搜尋並載入這個檔案,或者在vimrc檔案中加入

1
let g:ycm_global_ycm_extra_conf = 'your path to .ycm_extra_conf.py'

如果.ycm_extra_conf.py中include path等配置沒有問題,YCM已經可以工作了。

YCM更新很頻繁,最近版本已經可以和UltiSnip整合了。

2013-08-14更新

整合Syntastic

YCM很早就支援整合Syntastic了,上面demo裡面,程式碼前的出現紅色叉叉,就是YCM結合Syntastic爆出的語法錯誤。剛開始用YCM的時候,更看重其程式碼補全功能,Syntastic沒放在心上,結果發現越用越離不開了。當編寫C++程式碼的時候,每次游標懸停2秒鐘以上的時候,YCM都會在後臺掃描你當前的檔案,你剛剛輸入的程式碼有什麼編譯錯誤,馬上就能顯示出來,及時的改掉,不再積累到最後編譯的時候。當然這是現代IDE的標配功能,vim中也有外掛可以實現,但是有了YCM後,再用vundle安裝Syntastic,甚至不用任何配置就實現了這些功能,實在是太方便了。

程式碼跳轉

YCM支援程式碼跳轉了,又一項對程式開發極有用的功能,現在支援c, cpp, object-c, object-cpp, python程式碼跳轉到宣告和實現。特別對c和c++, 這個跳轉可不是像基於ctags的那些外掛,經常讓你在一大堆重名的tag里人肉搜尋,十跳九不中。得利於clang的強大功能,YCM的程式碼跳轉幾乎沒有失手,當然前提是你要設定好.ycm_extra_conf.py,程式碼被YCM解析時沒太多編譯錯誤。

主要功能是3個YcmCompleter的subcommands:

  • GoToDeclaration
  • GoToDefinition
  • GoToDefinitionElseDeclaration

在vim配置檔案中加上一行就搞定了

1
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>