自动命令

现在我们要介绍一个几乎和映射一样重要的概念:自动命令。

自动命令会告诉 Vim 在特定的时候运行特定的命令。让我们赶紧来看一个例子。

:edit foo 打开一个新的文件,然后马上用 :quit 关闭它。 查看下硬盘,你会注意到文件并不存在。这是因为 Vim 并没有真正创建这个文件,除非在第一时间保存下。

让我们修改下,这样一旦你编辑文件的时候,Vim 就会创建它们。运行以下命令:

:autocmd BufNewFile * :write

这有很多需要弄明白的东西,但是尽管试一试,能看到它正常工作。 再次运行 :edit foo,用 :quit 关闭它,然后看看硬盘。 这次文件会在那(当然是空的)。

你必须得关闭 Vim 来删除自动命令。我们会在以后的章节中讨论如何避免这个。

自动命令的结构

让我们更进一步来了解下我们刚刚创建的自动命令:

:autocmd BufNewFile * :write
         ^          ^ ^
         |          | |
         |          | 需要运行的命令
         |          |
         |          用来过滤事件的“模式”
         |
         想要监听的“事件”

命令的第一部分是我们想监听的事件类型。Vim 提供了很多事件以供监听。其中包括了:

这只是一小部分可用事件的例子。还有更多的可以用来做许许多多有趣的事情。

命令的后一部分是一个“模式”,能让你更加明确什么时候想触发命令。 启动一个新的 Vim 实例,运行以下命令:

:autocmd BufNewFile *.txt :write

这和上一个命令基本一样,但是它只会应用到以 .txt 为后缀名的文件。

试试运行 :edit bar,然后 :quit,然后 :edit bar.txt,然后 :quit。 你会看到 Vim 自动写入 bar.txt,但是不会写入 bar,因为它不匹配模式。

命令的最后一部分是事件触发时我们要运行的命令。 这是非常一目了然的,除了一点:不能在命令中使用像 <cr> 这样的特殊字符。 我们会在书中的后面部分讨论怎么规避这个限制,但是现在你只能忍受。

另外一个例子

让我们定义另外一个自动命令,这次使用一个不同的事件。运行命令:

:autocmd BufWritePre *.html :normal gg=G

这里我们稍微有点超前,因为要在本书的后面才会讲到 normal,但是现在你需要有点耐心, 因为当前想要理解这个有用的例子还是比较棘手的。

创建一个名为 foo.html 的新文件。用 Vim 编辑它,然后精确地输入以下文本,包括空白:

<html>
<body>
 <p>Hello!</p>
                 </body>
                  </html>

现在用 :w 保存这个文件。发生了什么?Vim 看起来在保存文件之前已经为我们重新缩进了!

到现在,我想让你相信运行 :normal gg=G 会告诉 Vim 重新缩进当前文件。 现在还不用担心这是如何工作的。

我们真正想要关注的是自动命令。 这里事件类型是 BufWritePre,指在写入任何文件之前会被触发的事件。

我们用了个 *.html 的模式,来确保这个命令只会在我们操作以 .html 结尾的文件是被触发。 这让我们把自动命令锁定在特定的文件上,这是个非常强大的概念,我们在以后还会继续探索。

多个事件

你可以创建一个单独的自动命令,并通过用一个逗号分隔来绑定多个事件。 运行命令:

:autocmd BufWritePre,BufRead *.html :normal gg=G

这几乎和上一个命令一样,除了它还会在我们读取一个 HTML 文件时重新随机代码,就和我们写入它时一样。 假如你的同事没有很好的缩进 HTML,那这个命令就会很有用。

Vimscript 中一个惯用语法是把 BufReadBufNewFile 事件配对在一起, 当打开一个特定类型的文件时,不管它是否存在,都会运行命令。运行以下命令:

:autocmd BufNewFile,BufRead *.html setlocal nowrap

每当你打开一个 HTML 文件时,都会关闭换行。

文件类型事件

最有用的事件之一是 FileType 事件。每当 Vim 设置缓冲的 filetype 时就会触发。

让我们为各种各样的文件类型建立一些有用的映射。运行以下命令:

:autocmd FileType javascript nnoremap <buffer> <localleader>c I//<esc>
:autocmd FileType python     nnoremap <buffer> <localleader>c I#<esc>

打开一个 Javascript 文件(后缀名为 .js 的文件),选择一行,然后键入 <localleader>c。 这行就会被注释了。

现在打开一个 Python 文件(后缀名为 .py 的文件),选择一行,然后键入 <localleader>c。 这行就会被注释了,但是是用的 Python 的注释符!

使用自动命令,配合着上一章节学的本地缓冲映射,我们可以对正在编辑的不同类型的文件创建特定的映射。

这减轻了我们写代码时的思想负担。我们只需要想着“注释这行”,而不用想着得移动到行首,然后添加一个注释符。

练习

浏览 :help autocmd-events,查看可以绑定到自动命令的所有事件。 你现在并不需要记住每一个。只要试着感受下能做些什么事。

使用 setlocal 来创建一些 FileType 自动命令,以你喜欢的方式为最喜欢的文件类型设置些选项。 你可能想基于不同的文件类型改变一些选项,比如 wraplistspell,和 number 等。

为你常用的文件类型再创建一些“注释这行”的自动命令。

把所有这些自动命令添加到你的 ~/.vimrc 文件。当然,用之前编辑和载入执行的快捷映射来迅速地完成!

原文地址:http://learnvimscriptthehardway.stevelosh.com/chapters/12.html