現(xiàn)在我們談?wù)撘粋€(gè)跟映射一樣重要的東西:自動(dòng)命令。
自動(dòng)命令可以讓Vim自動(dòng)執(zhí)行某些指定的命令,這些指定的命令會(huì)在某些事件發(fā)生的時(shí)候執(zhí)行。我們先看一個(gè)例子。
使用:edit foo
打開一個(gè)新文件,然后立即使用:quit
關(guān)閉。查看你的硬盤,你會(huì)發(fā)現(xiàn)這個(gè)文件并不存在。這是因?yàn)樵谀愕谝淮伪4孢@個(gè)文件之前,Vim_實(shí)際上_并沒有真正創(chuàng)建它。
讓我們對Vim做一些改變,使得Vim可以在你開始編輯文件的時(shí)候就創(chuàng)建它們。執(zhí)行下面的命令:
:autocmd BufNewFile * :write
這里面有很多需要進(jìn)一步說明的,不過在此之前我建議你先感受下它是怎么工作的。執(zhí)行:edit foo
,使用:quit
關(guān)閉,然后查看硬盤。這個(gè)時(shí)候文件會(huì)存在(當(dāng)然文件內(nèi)容為空)。
你只有關(guān)閉Vim才能刪除這個(gè)自動(dòng)命令。我們會(huì)在后面的章節(jié)說明如何避免這種情況。
讓我們來深入分析下我們剛才創(chuàng)建的自動(dòng)命令:
:autocmd BufNewFile * :write
^ ^ ^
| | |
| | 要執(zhí)行的命令
| |
| 用于事件過濾的“模式(pattern)”
|
要監(jiān)聽的“事件”
這個(gè)命令的第一部分是我們想監(jiān)聽的事件的類型。Vim提供了_很多_可以監(jiān)聽的事件。這些事件包括:
filetype
設(shè)置。上面只舉出了可用事件里面的很小一部分。還有很多其他的事件,你可以利用這些事件來做一些有趣的事情。
這個(gè)自動(dòng)命令的下一部分是一個(gè)“模式”,這個(gè)模式可以進(jìn)一步限定你要執(zhí)行的命令的執(zhí)行范圍。新開一個(gè)Vim實(shí)例,執(zhí)行下面的命令:
:autocmd BufNewFile *.txt :write
這個(gè)跟之前的那個(gè)自動(dòng)命令基本一樣,不過這個(gè)自動(dòng)命令只對后綴為.txt
的文件有效,也就是說當(dāng)你新建的文件為txt文件的時(shí)候,Vim會(huì)在文件創(chuàng)建的時(shí)候自動(dòng)執(zhí)行write命令將文件保存到硬盤上。
試試執(zhí)行:edit bar
,然后執(zhí)行:quit
,再執(zhí)行:edit bar.txt
,然后再執(zhí)行:quit
。你會(huì)發(fā)現(xiàn)Vim會(huì)自動(dòng)創(chuàng)建bar.txt
,但不會(huì)創(chuàng)建bar
,因?yàn)樗暮缶Y名不是txt,不跟模式匹配。
這個(gè)自動(dòng)命令的最后一部分是事件發(fā)生時(shí)我們想執(zhí)行的命令。這個(gè)部分很容易理解,跟我們執(zhí)行其他命令一樣,除了不能在這個(gè)命令中使用特殊的字符,例如<cr>
。我們會(huì)在本書后面的章節(jié)中談?wù)撊绾瓮黄七@個(gè)限制,現(xiàn)在你只需要遵守它就可以。
我們再定義一個(gè)自動(dòng)命令,這次使用一個(gè)不同的事件。執(zhí)行下面的命令:
:autocmd BufWritePre *.html :normal gg=G
這里用到了normal
命令,我會(huì)在本書的后面的章節(jié)里面講到它,這可能有點(diǎn)超前,不過我覺得這是一個(gè)很好的使用自動(dòng)命令的示例,所以請大家先忍受一下。
創(chuàng)建一個(gè)名為foo.html
的新文件。用Vim編輯它,并輸入下面的文本,請保證輸入的文本完全一致,包括空白符:
<html>
<body>
<p>Hello!</p>
</body>
</html>
執(zhí)行:w
保存這個(gè)文件。看看會(huì)發(fā)生了什么?Vim似乎在文件保存之前重新進(jìn)行了文本縮進(jìn)處理。
ok,請先相信我文本縮進(jìn)處理是:normal gg=G
干的,先別糾結(jié)于為什么:normal gg=G
可以干這個(gè)。
我們_應(yīng)該_把注意力放在自動(dòng)命令上。這個(gè)自動(dòng)命令里面用到的事件是BufWritePre
,這個(gè)事件會(huì)在你保存_任何_字符到文件之前觸發(fā)。
我們使用了*.html
這個(gè)模式,這個(gè)模式會(huì)保證命令只會(huì)在編輯html文件的時(shí)候被執(zhí)行。這就是自動(dòng)命令強(qiáng)大的地方,因?yàn)樗梢詫iT針對特定類型的文件來執(zhí)行我們想要執(zhí)行的命令。ok,讓我們繼續(xù)探索它吧。
你可以創(chuàng)建一個(gè)綁定_多個(gè)_事件的自動(dòng)命令,這些事件使用逗號分隔開。執(zhí)行下面的命令:
:autocmd BufWritePre,BufRead *.html :normal gg=G
這個(gè)跟上面的自動(dòng)命令基本一樣,不同的是它會(huì)讓Vim不僅在寫html文件的時(shí)候進(jìn)行縮進(jìn)處理,讀html文件的時(shí)候也會(huì)進(jìn)行縮進(jìn)處理。如果你有些同事不喜歡把HTML文件格式搞得漂亮點(diǎn),那么這個(gè)命令會(huì)很有用。
在Vim腳本編程中有一個(gè)不成文的規(guī)定,你應(yīng)該同時(shí)使用BufRead
和BufNewFile
(譯注:這里不是BufWritePre)這兩個(gè)事件來運(yùn)行命令,這樣當(dāng)你打開某個(gè)類型的文件,不論這個(gè)文件是否存在命令都會(huì)執(zhí)行。執(zhí)行下面的命令:
:autocmd BufNewFile,BufRead *.html setlocal nowrap
上面的命令會(huì)使得無論你在什么時(shí)候編輯HTML文件自動(dòng)換行都會(huì)被關(guān)閉。
最有用的事件是FileType
事件。這個(gè)事件會(huì)在Vim設(shè)置一個(gè)緩沖區(qū)的filetype
的時(shí)候觸發(fā)。
讓我們針對不同文件類型設(shè)置一些有用的映射。運(yùn)行命令:
:autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc>
:autocmd FileType python nnoremap <buffer> <localleader>c I#<esc>
打開一個(gè)Javascript文件(后綴為.js
的文件),將光標(biāo)移動(dòng)到某一行,敲擊<localleader>c
,光標(biāo)所在的那一行會(huì)被注釋掉。
現(xiàn)在打開一個(gè)Python文件(后綴為.py
的文件),將光標(biāo)移動(dòng)到某一行,敲擊<localleader>c
,同樣的那一行會(huì)被注釋掉,不同的是此時(shí)所用的是Python的注釋字符!
在自動(dòng)命令中包含我們上一章中學(xué)到的本地緩沖區(qū)映射,我們可以創(chuàng)建一些映射,這些映射會(huì)根據(jù)我們正在編輯的文件的類型來進(jìn)行不同的處理。
這可以為我們在編碼的時(shí)候減輕很多思考的負(fù)擔(dān)。如果要添加一個(gè)注釋,我們可能想到的是必須將光標(biāo)移動(dòng)到行首,然后添加一個(gè)注釋字符,而使用上面的映射,我們只需要簡單的將其理解為“注釋掉這一行”。
瀏覽:help autocmd-events
查看自動(dòng)命令可以綁定的所有事件。你不需要現(xiàn)在就記住每一個(gè)事件。僅僅只需要了解下你可以使用這些事件做哪些事情。
創(chuàng)建一些FileType
自動(dòng)命令使用setlocal
對你喜歡的文件類型做一些設(shè)置。你可以針對不同的文件類型設(shè)置wrap
、list
、?spell
和number
這些選項(xiàng)。
對一些你會(huì)經(jīng)常處理的文件類型創(chuàng)建一些類似“注釋掉這一行”的命令。
把所有這些自動(dòng)命令寫到你的~/.vimrc
文件里面。記住使用前面章節(jié)中提到過的快速編輯和加載~/.vimrc
文件的映射來做這個(gè)事情,這是必須的!
更多建議: