VIM学习笔记 自动命令(autocmd)

自动命令,是在指定事件发生时自动执行的命令。利用自动命令可以将重复的手工操作自动化,以提高编辑效率并减少人为操作的差错。

比如自定义以下函数,用于在文件中插入当前日期:

:function DateInsert()
:    $read !date
:endfunction

使用以下命令,可以手动调用此函数:

:call DateInsert()

而通过以下自动命令,则可以在保存文件时自动执行函数,而不再需要额外的手动操作:

:autocmd FileWritePre * :callDateInsert()<CR>

定义自动命令

可以使用以下格式的autocmd命令,来定义自动命令:

:autocmd [group] events pattern [nested] command

events参数

Vim内置了近80个事件,以下表格按照类别列示了较为常用的事件:

类别事件触发条件
读取BufNewFile编辑一个新文件时
BufReadPre读入新缓冲区之前
BufRead, BufReadPost读入新缓冲区之后
BufReadCmd开始编辑新缓冲区之前
FileReadPre使用:read命令读入文件之前
FileReadPost使用:read命令读入文件之后
StdinReadPre由标准输入设备读入缓冲区之前
StdinReadPost由标准输入设备读入缓冲区之后
写入BufWrite, BufWritePre将整个缓冲区写入文件时
BufWritePost将整个缓冲区写入文件之后
BufWriteCmd将整个缓冲区写入文件之前
缓冲区BufAdd, BufCreate将缓冲区加入缓冲区列表之后
BufDelete从缓冲区列表中移除缓冲区之前
BufEnter进入缓冲区之后
BufLeave离开缓冲区之前
BufWinEnter在窗口中显示缓冲区之后
BufWinLeave从窗口中关闭缓冲区之前
BufNew创建缓冲区之后
BufUnload卸载缓冲区之前
选项FileType设置'filetype'选项之后
Syntax设置'syntax'选项之后
EncodingChanged'encoding'选项改变之后触发命令;
OptionSet设置任何选项之后
启动
退出
VimEnterVim启动并载入初始化文件之后
GUIEnter启动GUI之后
VimLeavePre改写viminfo文件之前,退出Vim之前
VimLeave改写viminfo文件之后,退出Vim之前
其它FileChangedShell当文件的最后修改时间等属性发生改变时
InsertEnter进入插入模式时
InsertLeave离开插入模式时
FocusGainedVim成为当前窗口时
FocusLostVim不再是当前窗口时
WinEnter进入窗口时
WinLeave离开窗口时
CursorMoved在常规模式下移动光标时
CursorMovedI在插入模式下移动光标时
CursorHold当超过'updatetime'所指定时间用户没有输入时
vimResized窗口尺寸变化之后

假设我们打开文件并输入文本,然后保存并退出,那么这些操作将以下顺序触发一系列事件:

操作事件
启动Vim并创建默认窗口BufWinEnter
创建默认缓冲区BufEnter
:edit a.txtVimEnter
创建新缓冲区BufNew
将新缓冲区加入到缓冲区列表之中BufAdd
退出默认缓冲区BufLeave
退出默认窗口BufWinLeave
将默认缓冲区从缓冲区列表之中移除BufUnload
删除默认缓冲区BufDelete
将a.txt文件读入新缓冲区BufReadCmd
激活新缓冲区BufEnter
激活新窗口BufWinEnter
进入插入模式InsertEnter
输入文本CursorMovedI
退出插入模式InsertLeave
:wqBufWriteCmd
退出新窗口BufWinLeave
将新缓冲区从缓冲区列表之中移除BufUnload
准备退出VimVimLeavePre
退出VimVimLeave

Source: Event-driven scripting and automation

您可以使用以下命令,获得各个事件的详细说明:

:help autocommand-events

pattern参数

匹配模式用来指定应用自动命令的文件。在匹配模式中,可以使用以下特殊字符:

*匹配任意长度的任意字符
?匹配单个字符
\?匹配字符'?'
.匹配字符'.'
,用于分割多个pattern
\,匹配字符','

可以使用逗号来分割多个模式,以匹配多种类型的文件。例如以下命令,将对于.c和.h文件设置'textwidth'选项:

:autocmd BufRead,BufNewFile *.c,*.h set tw=0

您可以使用以下命令,获得匹配模式的详细说明:

:help autocmd-patterns

nested参数

默认情况下,自动命令并不会嵌套执行。例如在自动命令中执行:e或:w命令,将不会再次触发BufRead和BufWrite事件。而使用nested参数,则可以激活嵌套的事件。

:autocmd FileChangedShell *.c nested e!

查看自动命令

使用以下命令,可以列出所有自动命令:

:autocmd

autocm

你会发现自动命令的列表将会非常的长,其中既包括了在vimrc文件中用户定义的自动命令,也包括了各种插件定义的自动命令。

如果在命令中指定了group,那么将会列出所有与指定group相匹配的自动命令;同理,也可以在命令中指定event和pattern,以查看相匹配的自动命令:

:autocmd filetypedetect * *.htm

autocm_list

删除自动命令

使用以下命令,可以删除所有自动命令:

:autocmd!

注意:此操作也将删除插件所定义的自动命令,请谨慎操作。

使用以下命令,可以删除指定组的自动命令:

:autocmd! group

在命令中指定组、事件和匹配模式,可以删除特定的自动命令:

autocmd! Unfocussed FocusLost *.txt

在命令中使用特殊字符“*”来指代所有事件或文件。例如以下命令,将删除Unfocussed组中所有针对txt文件的自动命令:

autocmd! Unfocussed * *.txt

在命令中忽略文件匹配模式,那么所有针对指定事件的针对命令都将被删除。例如以下命令,将删除Unfocussed组在所有针对FocusLost事件的自动命令:

autocmd! Unfocussed FocusLost

自动命令组

通过:augroup命令,可以将多个相关联的自动命令分组管理,以便于按组来查看或删除自动命令。例如以下命令,将C语言开发的相关自动命令,组织在“cprogram”组内:

:augroup cprograms
:    autocmd!
:    autocmd FileReadPost *.c :set cindent
:    autocmd FileReadPost *.cpp :set cindent
:augroup END

如果我们针对同样的文件和同样的事件定义了多条自动命令,那么当满足触发条件时将分别执行多条自动命令。因此,建议在自动命令组的开头增加:autocmd!命令,以确保没有重复的自动命令存在。

您可以使用以下命令,获得自动命令组的帮助信息:

:help :augroup

自动命令选项

通过eventignore选项,可以忽略指定的事件,而不触发自动命令。例如使用以下命令,将忽略进入窗口和离开窗口的事件:

:set eventignore=WinEnter,WinLeave

如果希望忽略所有事件,那么可以使用以下设置:

:set eventignore=all

命令小结
:autocmd定义/查看自动命令
:autocmd!删除自动命令
:augroup定义自动命令组
:set eventignore设置忽略的事件

Ver: 2.0 | YYQ<上一篇 | 目录 下一篇>