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