Vimscript编程指南

Autocommands

现在我们要讨论一个和映射差不多主要的话题:autocommands

Autocommands是一个告诉vim在发送特定事情的时候运行特定的程序的一个方式。让我们先来看看一个例子。

首先,用:edit foo打开一个新文件然后马上用:quit来关闭它。看看你的磁盘,你会发现这个文件并不存在。这是因为当你新建一个文件的时候如果你没有保存的话,vim是不会真正去创建这个文件的。

下面让我们来改变vim的这个行为,让它在只要你编辑文件的时候就立马创建它。运行下面的命令:

:autocmd BufNewFile * :write

这个命令涉及的东西比较多,先试试看会有什么功能。再次运行:edit foo,然后用:quit关闭,再看看你的磁盘。这次文件被创建了(不过是空的)。

你需要关闭vim来移除这个autocommand,后面我们会讨论这个在vim里移除的。

Autocommand的结构

下面我们来看看刚刚创建的autocommand的结构:


    :autocmd BufNewFile * :write
                        ^          ^ ^
                        |           |  |
                        |           |  The command to run.
                        |           |
                        |          A "pattern" to filter the event.
                        |
               The "event" to watch for.

autocommand的第一部分是我们要关注的事件类型。vim提供了多种可以关注的事件。它们包含:

  • 开始编辑一个新的文件
  • 读一个文件,无论这个文件是否存在
  • 切换一个缓存的文件类型
  • 一段事件没有按下任何键
  • 进入insert模式
  • 退出insert模式

以上只是vim支持的事件的一些很小的例子——vim里有更多的可以用来完成一些有趣的功能的事件。

接下来的部分是用来给执行的autocommand指定更明确的信息的一个模式 。打开一个新的vim实例,运行下面的命令:

:autocommand BufNewFile *.txt :write

这个命令和上面的功能差不多,但是这次只会对后缀为.txt的文件有作用。

试着用:edit bar,然后用:quit,再试试用:edit bar.txt,然后用:quit。你会发现vim创建了bar.txt文件,但是没有创建bar文件,因为bar不匹配前面的模式。

命令的最后一部分是当事件发生时我们要运行的命令,这个就很明显了,除了一点要注意的,在这里不能使用类似于之类的特殊字符串。关于这个限制我们后面会讨论的,但是现在你必须记住它。

另外一个例子

现在我们来定义另一个autocommand,这次我们用一个不同的事件。运行下面的命令: :autocmd BufWrite *.html :normal gg=G

这里面用的命令有些超前,在后面的章节里我们才会讨论normal命令,不过这里你只能将就我了,因为这是个很有用的例子。

打开一个新的文件,命名为foo.html。并且输入下面的文本,要保证一模一样,包含空格:


  

 

Hello!

现在用:w来保存文件,发生了什么呢?vim在关闭文件之前自动进行了格式化。

现在你只需要相信我:normal gg=G命令会格式化当前的文件。暂时不用担心它是怎么起作用的。

我们需要关注的是这个autocommand。它的事件类型是BufWrite,它表示当有文件要写入的时候发生的实际。

我们用*.html这个模式来保证这个命令只会对html后缀的文件起作用。这个让我们的autocommand只对特定的文件执行,这是个很强大的功能,我们后面会继续探讨的。

3、多事件监听

你可以在一个命令里监听多个事件,事件之间用逗号分隔。运行下面的命令: :autocmd BufWrite,BufRead *.html :normal gg=G

这个命令和上面的命令差不多,只不过它对文件打开和关闭的操作都会执行格式化的动作。这个命令在当我们和那些不格式化HTML的人一起工作时非常的有用。

在vim脚本里比较常用的一种方式就是,使用BufRead和BufNewFile事件对来操作某种类型的文件,无论是这个文件已经存在还是不存在。运行下面的命令: :autocmd BufRead,BufNewFile *.html :setlocal nowrap

这个命令的功能是:当你在打开HTML文件进行编辑的时候,它就会关闭自动换行的功能。

文件类型事件

文件类型事件是比较常用的事件之一。这个事件发生在Vim设置一个文件的filetype时。

我们来对不同的文件类型建立一些有用的映射。运行下面的命令? :autocmd FileType javascript nnoremap <buffer> <localleader>c I// :autocmd FileType python nnoremap <buffer> <localleader>c I#

打开一个javascript文件(以.js结尾的文件),挑选一行,然后按键+c,这个命令会注释当前行。

现在打开一个python文件(以py结尾的文件),挑选一行,然后按c,这个命令也会注释当前行,但是这次用的是python的注释符号。

用autocommand和之前学到的本地缓存映射组合起来,可以针对我们所编辑的不同类型的文件创建不同的映射。

这个减少了我们在编码时需要考虑不同类型的文件的动作。当需要注释时我们只需要考虑“注释这一行”而不需要把光标移动到当前行的开始处,然后插入一个注释符。

你可能会发现,执行完上面的命令后,我们会停留在insert模式。不行的是我们现在无法修复这个功能,后面我们会讨论这个问题的。

练习

  • 简要阅读一下:help autocmd-events看看有哪些事件可以监听。你不需要记住没一个事件,只是了解一下即可。
  • 用setlocal对你常用的几种文件类型创建一些有用的autocommand。一些你需要对不同文件类型自定义的选项是:warp,list和numer。
  • 对你常用的文件创建一个快速注释的命令
  • 把上面的autocommand加入你的vimrc文件里,当然要用之前的快捷键,要快!