文章目錄
- 外掛程式簡介
- 外掛程式安裝
- 外掛程式使用
- 外掛程式局限性
- 外掛程式擴充
- 總結
自己動手擴充vim外掛程式——code_complete.vim篇
By 馬冬亮(凝霜 Loki)
一個人的戰爭(http://blog.csdn.net/MDL13412)
外掛程式簡介
code_complete.vim是一款通用外掛程式,具有用於補全函數參數,插入程式碼片段等功能。目前外掛程式作者已經將項目遷移到GitHub上進行託管。
是官方的Demo(函數參數補全功能要配合ctags使用):
外掛程式安裝 將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
此外掛程式的擴充並不難,讀者可以將常用的程式碼片段擴充進去,提升編碼效率。另外,程式員用的編輯器應該具有良好的擴充性:-)