前面幾章我們學習了自動命令。執行下面命令:
~~~
:autocmd BufWrite * :echom "Writing buffer!"
~~~
現在使用`:write`命令將當前緩沖區寫入文件,然后執行`:messages`命令查看消息日志。你會看到`Writing buffer!`在消息列表中。
然后將當前緩沖區寫入文件,執行`:messages`查看消息日志。你會看到`Writing buffer!`在消息列表中出現了兩次。
現在再次執行上面的自動命令:
~~~
:autocmd BufWrite * :echom "Writing buffer!"
~~~
再次將當前緩沖區寫入文件并執行`:messages`命令。你會看到`Writing buffer!`在消息列表中出現了_4_次,這是怎么回事?
這是因為當你以上面的方式創建第二個自動命令的時候,Vim沒辦法知道你是想替換第一個自動命令。在上面的示例中,Vim創建了兩個_不同_的自動命令,并且這兩個命令剛好做同樣的事情。
## 這會有什么問題?
既然你現在知道了Vim可能創建兩個完全一樣的自動命令,你可能會想:“有什么大不了?只要別這么干就可以!”。
問題是當你加載你的`~/.vimrc`文件的時候,Vim會重新讀取整個文件,包括你所定義的任何自動命令!這就意味著每次你加載你的`~/.vimrc`文件的時候,Vim都會復制之前的自動命令,這會降低Vim的運行速度,因為它會一次又一次地執行相同的命令。
你可以執行下面的命令模擬這種情況:
~~~
:autocmd BufWrite * :sleep 200m
~~~
現在將當前緩沖區寫入文件。你可能注意到Vim在寫入文件的時候有點緩慢,當然也你可能注意不到。現在執行上面的自動命令三次:
~~~
:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m
~~~
再次寫文件。這次會更明顯。
當然你不會創建任何只是進行sleep而不做任何事情的自動命令,不過一個使用Vim的老鳥的`~/.vimrc`文件可以輕易達到1000行,其中會有很多自動命令。再加上安裝的插件中的自動命令,這肯定會影響Vim的速度。
## 把自動命令放到組中(Grouping Autocommands)
對于這個問題,Vim有一個解決方案。這個解決方案的第一步是將相關的自動命令收集起來放到一個已命名的組(groups)中。
新開一個Vim實例,這樣可以清除之前所創建的自動命令。然后運行下面的命令:
~~~
:augroup testgroup
: autocmd BufWrite * :echom "Foo"
: autocmd BufWrite * :echom "Bar"
:augroup END
~~~
中間兩行的縮進沒有什么含義,如果你不想輸入的話可以不輸。
將一個緩沖區寫入文件然后執行`:messages`。你應該可以在消息日志列表中看到`Foo`和`Bar`。現在執行下面的命令:
~~~
:augroup testgroup
: autocmd BufWrite * :echom "Baz"
:augroup END
~~~
當你再次將緩沖區寫入文件的時候猜猜會發生什么。ok,你也許已經有結果了,重新寫入緩沖區,然后執行`:messages`命令,看看你猜對了沒。
## 清除自動命令組
當你寫入文件的時候發生什么了?猜對了么?
如果你認為Vim會替換那個組,那么你猜錯了。不要緊,很多人剛開始的時候都會這么想(我也是)。
當你多次使用`augroup`的時候,Vim每次都會組合那些組。
如果你想清除一個組,你可以把`autocmd!`這個命令包含在組里面。執行下面的命令:
~~~
:augroup testgroup
: autocmd!
: autocmd BufWrite * :echom "Cats"
:augroup END
~~~
現在試試寫入文件然后執行`:messages`查看消息日志。這次Vim只會輸出`Cats`在消息列表中。
## 在Vimrc中使用自動命令
既然我們現在知道了怎么把自動命令放到一個組里面以及怎么清除這些組,我們可以使用這種方式將自動命令添加到`~/.vimrc`中,這樣每次加載它的時候就不會復制自動命令了。
添加下面的命令到你的`~/.vimrc`文件中:
~~~
augroup filetype_html
autocmd!
autocmd FileType html nnoremap <buffer> <localleader>f Vatzf
augroup END
~~~
當進入`filetype_html`這個組的時候,我們會立即清除這個組,然后定義一個自動命令,然后退出這個組。當我們再次加載`~/.vimrc`文件的時候,清除組命令會阻止Vim添加一個一模一樣的自動命令。
## 練習
查看你的`~/.vimrc`文件,然后把所有的自動命令用上面組的方式包裹起來。如果你覺得有必要,可以把多個自動命令放到一個組里面。
想想上一節的示例中的自動命令是干啥的。
閱讀`:help autocmd-groups`。
- 前言
- 鳴謝
- 預備知識
- 打印信息
- 設置選項
- 基本映射
- 模式映射
- 精確映射
- Leaders
- 編輯你的Vimrc文件
- Abbreviations
- 更多的Mappings
- 鍛煉你的手指
- 本地緩沖區的選項設置和映射
- 自動命令
- 本地緩沖區縮寫
- 自動命令組
- Operator-Pending映射
- 更多Operator-Pending映射
- 狀態條
- 負責任的編碼
- 變量
- 變量作用域
- 條件語句
- 比較
- 函數
- 函數參數
- 數字
- 字符串
- 字符串函數
- Execute命令
- Normal命令
- 執行normal!
- 基本的正則表達式
- 實例研究:Grep 運算符(Operator),第一部分
- 實例研究:Grep運算符(Operator),第二部分
- 實例研究:Grep運算符(Operator),第三部分
- 列表
- 循環
- 字典
- 切換
- 函數式編程
- 路徑
- 創建一個完整的插件
- 舊社會下的插件配置方式
- 新希望:用Pathogen配置插件
- 檢測文件類型
- 基本語法高亮
- 高級語法高亮
- 更高級的語法高亮
- 基本折疊
- 高級折疊
- 段移動原理
- Potion段移動
- 外部命令
- 自動加載
- 文檔
- 發布
- 還剩下什么?