自动命令组
前几章节,我们学习了自动命令。运行以下命令:
:autocmd BufWrite * :echom "Writing buffer!"
现在用 :write
写入当前缓冲,然后运行 :messages
查看信息日志。
你应该会在列表里看到 Writing buffer!
的信息。
现在再次写入当前缓冲,然后运行 :messages
查看信息日志。
你应该会在列表里看到两条 Writing buffer!
的信息。
现在再次运行完全相同的自动命令:
:autocmd BufWrite * :echom "Writing buffer!"
再一次写入当前缓冲,运行 :messages
。你会在列表中看到四条 Writing buffer!
的信息。
发生了什么?
当你创建了一个像这样的自动命令,Vim 没法知道你是不是想替换掉一个已经存在的命令。 在这个例子中,Vim 创建了两个独立的自动命令,而它们碰巧做的是同样的事情。
问题
既然你知道了可能会创建重复的自动命令,可能会想:“那又如何?只要别这么做!”
但问题是载入执行 ~/.vimrc
文件会重新读取整个文件,包括已经定义过的任何自动命令!
这意味这每次载入执行 ~/.vimrc
时,都会复制这些自动命令,使 Vim 运行变得缓慢,
因为会不停地执行相同的命令。
为了模拟这种行为,试试运行以下命令:
:autocmd BufWrite * :sleep 200m
现在写入当前缓冲。你可能注意到 Vim 在写入时轻微的停滞,也可能没注意到。 现在再运行三次这个命令:
:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m
再次写入文件。这次停滞状态会更加明显。
显然不会有哪个自动命令是什么事都不做而只是休眠的,但是一个老练的 Vim 用户可以轻松的让 ~/.vimrc
达到 1,000 行,
而其中很多都是自动命令。结合所有已安装插件中的自动命令,肯定会影响性能的。
归类自动命令组
Vim 有一个针对这个问题的解决办法。第一步就是把相关的自动命令归类到一个指定的组里。
打开一个新的 Vim 实例以清除之前的自动命令,然后运行以下命令:
:augroup testgroup
: autocmd BufWrite * :echom "Foo"
: autocmd BufWrite * :echom "Bar"
:augroup END
中间两行的缩进是无意义的。如果不想的话就不用这么做了。
写入文件,然后检查 :messages
。你应该会看到 Foo
和 Bar
。现在运行以下命令:
:augroup testgroup
: autocmd BufWrite * :echom "Baz"
:augroup END
猜猜看当你再次写入缓冲时会发生什么。一旦想好了,写入缓冲然后检查 :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
。
原文地址:http://learnvimscriptthehardway.stevelosh.com/chapters/14.html