自己動手擴充套件vim外掛——code_complete.vim篇

凝霜發表於2012-10-22

自己動手擴充套件vim外掛——code_complete.vim篇

By 馬冬亮(凝霜  Loki)

一個人的戰爭(http://blog.csdn.net/MDL13412)

外掛簡介

        code_complete.vim是一款通用外掛,具有用於補全函式引數,插入程式碼片段等功能。目前外掛作者已經將專案遷移到GitHub上進行託管。

        下圖是官方的Demo(函式引數補全功能要配合ctags使用):

code_complete官方Demo

外掛安裝

        將code_complete.vim拷貝至~/.vim/plugin目錄下。
        利用Ctags生成tags檔案(在程式碼目錄下執行,遞迴解析當前資料夾),程式碼如下:
ctags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ .
        將生成的tags檔名改成xxx_tags,拷貝至~/.vim/tags目錄中,在~/.vimrc中加入如下程式碼:
set tags+=~/.vim/tags/xxx_tags

外掛使用

        此款外掛使用非常簡單,只需使用<tab>鍵即可觸發相應的功能,下面將詳細講解具體的用法:

        註釋

        code_complete外掛提供兩種風格的註釋,一種是/*  */形式的標準C語言註釋,而另一種是/**<  */形式的Doxygen風格的用於在一行後進行註釋的文件註釋(此外掛沒有提供自動生成函式文件註釋的功能,此功能可以使用更專業的外掛DoxygenToolkit.vim來實現)。



        預處理命令

        標頭檔案包含


        C語言邏輯結構





        主函式


        namespace


        函式引數補全

外掛侷限性

        通過上面的演示,我們發現了此款外掛的一些侷限性:

  • 自動補全的程式碼風格跟我們使用的不同(上面的例子已經改為我自己程式碼風格)。
  • if else結構、switch結構的分支無法手動指定;
  • 使用者自定義函式時,沒有函式模板可以使用;

外掛擴充套件

        自定義程式碼風格

        下面以if else結構進行說明,我們先檢視沒有更改前的程式碼:

let g:template['c']['ife'] = "if( ".g:rs."...".g:re." )\<cr>{\<cr>".g:rs."...".g:re."\<cr>} else\<cr>{\<cr>".g:rs."...". g:re."\<cr>}"
        我們來檢視其在vim中的樣式:

        在if的括號中,條件表示式與括號間有一個空格,這和我們的風格不一致,我們可以按照如下程式碼進行更改:

let g:template['c']['ife'] = "if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} else\<cr>{\<cr>".g:rs."...".g:re."\<cr>}"

        注:在VimScript中,字串可以是"或'形式的字串,字串使用.進行連線,\<cr>是鍵盤上的回車,\用於在字串中進行轉義。檢視vim中的按鍵對映,在vim中使用:help keycode進行檢視。let g:template['c']['xxx']中的[xxx]是程式碼補全的觸發序列。

        對於其它邏輯結構,主要都是空格與我們的風格不一致,可按以上原則進行定製。

        if else結構和switch結構定製

        下面我以if else結構演示我擴充套件後的外掛,程式碼會在後面給出:


        對於擴充套件後的if else結構,其用法為:

                ife[x]<tab>  在插入模式下輸入ife,後面接else if()的分支個數,然後按<tab>鍵展開。

        我擴充套件了0~9的分支情況,下面給出0~3的程式碼定義:

let g:template['c']['ife0'] = "if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} else\<cr>{\<cr>".g:rs."...".
            \g:re."\<cr>}"
let g:template['c']['ife1'] = "if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else\<cr>{\<cr>".g:rs."...".
            \g:re."\<cr>}"
let g:template['c']['ife2'] = "if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else\<cr>{\<cr>".g:rs."...".
            \g:re."\<cr>}"
let g:template['c']['ife3'] = "if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".
            \"else\<cr>{\<cr>".g:rs."...".
            \g:re."\<cr>}"

        相信有程式設計基礎的讀者已經看出規律了,即有多少個else if分支,就有多少個\"else if (".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>} ".

        下面我們來看一下switch的演示:


        對於擴充套件後的switch結構,其用法為:

                switch[x]<tab>  在插入模式下輸入switch,後面接case的分支個數,然後按<tab>鍵展開。

        我擴充套件了1~9的分支情況,下面給出0~3的程式碼定義:

let g:template['c']['switch1'] = "switch (".g:rs."...".g:re.")\<cr>{\<cr>case ".
            \g:rs."...".g:re.":\<cr>break;".
            \"\<cr>default:\<cr>break;\<cr>}"
let g:template['c']['switch2'] = "switch (".g:rs."...".g:re.")\<cr>{\<cr>case ".
            \g:rs."...".g:re.":\<cr>break;".
            \"\<cr>case ".g:rs."...".g:re.":\<cr>break;".
            \"\<cr>default:\<cr>break;\<cr>}"
let g:template['c']['switch3'] = "switch (".g:rs."...".g:re.")\<cr>{\<cr>case ".
            \g:rs."...".g:re.":\<cr>break;".
            \"\<cr>case ".g:rs."...".g:re.":\<cr>break;".
            \"\<cr>case ".g:rs."...".g:re.":\<cr>break;".
            \"\<cr>default:\<cr>break;\<cr>}"

        函式模板

        下面我們先看擴充套件後的效果:


        通過例項可以看出,使用了函式模板後,減少了我們的輸入次數及游標移動次數,很好的提升了程式設計效率,下面介紹其用法:

                f[x]<tab>  在插入模式下輸入f,後面接函式引數的個數,然後按<tab>鍵展開。

        下面給出0~3個引數的程式碼:

let g:template['c']['f0']=g:rs."...".g:re."()\<cr>{\<cr>".g:rs."...".g:re."\<cr>}"
let g:template['c']['f1']=g:rs."...".g:re."(".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>}"
let g:template['c']['f2']=g:rs."...".g:re."(".g:rs."...".g:re.", ".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>}"
let g:template['c']['f3']=g:rs."...".g:re."(".g:rs."...".g:re.", ".g:rs."...".g:re.", ".g:rs."...".g:re.")\<cr>{\<cr>".g:rs."...".g:re."\<cr>}"

總結

        此外掛目前之擴充套件了C語言,對於C++的擴充套件尚未完成,擴充套件後外掛的下載地址:http://download.csdn.net/detail/mdl13412/4674025

        此外掛的擴充套件並不難,讀者可以將常用的程式碼片段擴充套件進去,提升編碼效率。另外,程式設計師用的編輯器應該具有良好的擴充套件性:-)

相關文章