vim是一個強大的編輯器,以命令行操作的快速性著稱。不過,玩着玩着,感覺也不能解決自己工作中的一些特別的問題。所以現在你可以有三種方法來自定義一些命令,完成自己個性化的需求。下面就來一一嘗試。
【宏命令】
可以用宏命令來批量處理。不過退出之后就消失了,下次不能再使用,所以這個不是一個永久性的方法。短時解決重復工作是非常高效的。
【自定義命令】
可以自定義命令,這個也是簡短操作的一個好方法。例如:在gvim下將當前文本去掉重復行,就可以使用以下兩個命令:
:sort :g/^\(.\+\)$\n\1/d
如果每次都敲入這兩行命令,估計你也嫌麻煩。可以自定義為一個命令,這樣就可以直接用簡短方式執行了。
:command! Td :sort|:g/^\(.\+\)$\n\1/d
將上面這一個作為一個獨立行放入vim的配置文件中。window下是Vim\_vimrc,linux下是~/.vimrc文件。這樣啟動vim的時候就會自動定義好這個命令,直接就可以使用了。
關於command自定義冒號命令,我這里羅嗦幾句講一下。
1.以:command開頭,如果是重新定義,command后加!號。沒有定義過也可以加上。如果需要指定可能的參數個數,可以加上-xargs=n配置項。
2.空格之后緊跟新的命令名字,請以大寫字母開頭,后面的是否采用駝峰命名法取決於你自己。
3.然后就是命令操作的集合了。用|分割多個命令,這里跟平常|在編程中的語義不同,請注意。
對於這樣短一點的命令可以采用這種方式去做,如果操作太多,那么需要在command后面加入很多代碼,這不是vim想看到的。可以將多余的代碼放入函數中,這是今天我想說的主題。
【插件開發】
插件文件放在\ftplugin類似的目錄中,以.vim為后綴。例如:
// art.vim if exists("b:did_ftplugin") finish endif run ftplugin/lisp.vim setl lw-=if setl lw+=def-art-fun,deffacts,defglobal,defrule,defschema, \for,schema,while
其中一開始判斷是否已經加載了文件,防止重復加載。然后調用了lisp.vim文件,最后進行了一些操作,還可以繼續定義自己的函數。這就是插件的常見基本結構了。
【開發實例】
首先,加入頭部,防止重復加載。
if &cp || exists("g:loaded_filter") finish endif let g:loaded_filter = "v1"
這里你還可以自己修改一下loaded_filter,改為其他變量,這樣就能夠區分你自己的插件了。
然后是定義函數:
func Del(part) let s:num = line('$') while(s:num) let s:str = getline(s:num) let s:num -= 1 let s:str = substitute(s:str, a:part, '', '') call setline(s:num + 1, s:str) unlet s:str endwhile unlet s:num return endfunc
函數都是func開頭,名字大寫字母開頭,可以傳遞參數。我簡單說一下這個函數的功能:
首先獲取全文行數,放到num變量中。然后調用getline函數,取出0至num-1行的內容,將part部分替換為空字符串,也就是刪除。然后調用setline函數,更新該行的內容為替換之后的內容。這個函數很簡單,作用就是從全文中刪掉一個字符串。要在vim中執行這個函數只需要輸入:
:call Del('j')
回車之后就會執行。如果提示沒有找到Del函數,可以在配置文件中加入對自定義文件的引用:
source $VIMRUNTIME/ftplugin/filter.vim
然后重啟vim,再次執行就可以了。
如果我們想自定義刪除兩個符號之間的內容,那么可以將上面函數substitute中的第二個參數修改為正則表達式,進行匹配和替換就行了。
這里我要講另外一個實例:
func Uc(flag) let s:pre = a:flag[0] let s:end = a:flag[1] let s:num = line('$') let s:count = {} while(s:num) let s:str = getline(s:num) let s:num -= 1 let s:first = stridx(s:str, s:pre) if( s:first == -1) continue endif let s:first += 1 let s:second = stridx(s:str, s:end) if( s:second == -1) continue endif let s:str = strpart(s:str, s:first, s:second - s:first) if( has_key(s:count, s:str) ) let s:count[s:str] += 1 else let s:count[s:str] = 1 endif unlet s:str endwhile for key in keys(s:count) echo 'key=' key ',value=' s:count[key] endfor unlet s:pre unlet s:end unlet s:num unlet s:count return endfunc
這個函數的作用是根據參數字符串part的第一個字符和第二個字符去搜索全文每行,按照匹配到的這兩個字符之間的內容進行統計,計算出重復量,顯示到命令輸入欄的上方。這個功能也可以通過linux下的awk來實現,不過經過這樣自己定義之后的函數可以直接調用,一次開發,多次使用,效率更高。
【總結】
我想講述的就是這些了,如果你還有更多興趣想學習更多,可以參考vim用戶手冊,是一個pdf的電子書,不用緊張,有很好的中文翻譯版本,其中詳細列舉了vim插件開發的語法。
你還可以通過:function命令查看現在已經定義的函數,然后:function Del查看Del函數的定義內容,這樣來學習更多的插件編程技巧。
你還可以通過:help substitute來查看substitute函數的相關文檔,這個文檔一般是英文的。計算機英文只要你堅持看,你會發現他們的措辭很類似,單詞也就是那幾個,比較好掌握。
你還可以去插件目錄下去閱讀其他插件的源代碼,其中不懂的函數就help一下,然后練習練習就會了,更多插件完全就難不倒你了。
所以現在你就可以去動手開始做自己的插件了,祝你成功。