文章目录
转自:https://yyq123.github.io/learn-vim/learn-vi-49-01-autocmd.html
autocmd
自动命令,是在指定事件发生时自动执行的命令。利用自动命令可以将重复的手工操作自动化,以提高编辑效率并减少人为操作的差错。
比如自定义以下函数,用于在文件中插入当前日期:
c#
function DateInsert()
$read !date
endfunction
使用以下命令,可以手动调用此函数:
powershell
:call DateInsert()
而通过以下自动命令,则可以在保存文件时自动执行函数,而不再需要额外的手动操作:
powershell
:autocmd FileWritePre * :callDateInsert()<CR>
定义自动命令
可以使用以下格式的autocmd命令,来定义自动命令:
kotlin
:autocmd [group] events pattern [nested] command
- 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 | 设置任何选项之后 |
启动退出 | VimEnter | Vim启动并载入初始化文件之后 |
启动退出 | GUIEnter | 启动GUI之后 |
启动退出 | VimLeavePre | 改写viminfo文件之前,退出Vim之前 |
启动退出 | VimLeave | 改写viminfo文件之后,退出Vim之前 |
其它 | FileChangedShell | 当文件的最后修改时间等属性发生改变时 |
其它 | InsertEnter | 进入插入模式时 |
其它 | InsertLeave | 离开插入模式时 |
其它 | FocusGained | Vim成为当前窗口时 |
其它 | FocusLost | Vim不再是当前窗口时 |
其它 | WinEnter | 进入窗口时 |
其它 | WinLeave | 离开窗口时 |
其它 | CursorMoved | 在常规模式下移动光标时 |
其它 | CursorMovedI | 在插入模式下移动光标时 |
其它 | CursorHold | 当超过'updatetime'所指定时间用户没有输入时 |
其它 | vimResized | 窗口尺寸变化之后 |
假设我们打开文件并输入文本,然后保存并退出,那么这些操作将以下顺序触发一系列事件:
操作 | 事件 |
---|---|
启动Vim并创建默认窗口 | BufWinEnter |
创建默认缓冲区 | BufEnter |
:edit a.txt | VimEnter |
创建新缓冲区 | BufNew |
将新缓冲区加入到缓冲区列表之中 | BufAdd |
退出默认缓冲区 | BufLeave |
退出默认窗口 | BufWinLeave |
将默认缓冲区从缓冲区列表之中移除 | BufUnload |
删除默认缓冲区 | BufDelete |
将a.txt文件读入新缓冲区 | BufReadCmd |
激活新缓冲区 | BufEnter |
激活新窗口 | BufWinEnter |
进入插入模式 | InsertEnter |
输入文本 | CursorMovedI |
退出插入模式 | InsertLeave |
:wq | BufWriteCmd |
退出新窗口 | BufWinLeave |
将新缓冲区从缓冲区列表之中移除 | BufUnload |
准备退出Vim | VimLeavePre |
退出Vim | VimLeave |
pattern参数
匹配模式用来指定应用自动命令的文件。在匹配模式中,可以使用以下特殊字符:
? | 匹配单个字符 |
? | 匹配字符'?' |
. | 匹配字符'.' |
, | 用于分割多个pattern |
, | 匹配字符',' |
可以使用逗号来分割多个模式,以匹配多种类型的文件。例如以下命令,将对于.c和.h文件设置'textwidth'选项: |
csharp
:autocmd BufRead,BufNewFile *.c,*.h set tw=0
您可以使用以下命令,获得匹配模式的详细说明:
csharp
:help autocmd-patterns
nested参数
默认情况下,自动命令并不会嵌套执行。例如在自动命令中执行:e
或:w
命令,将不会再次触发BufRead和BufWrite事件。而使用nested参数,则可以激活嵌套的事件。
csharp
:autocmd FileChangedShell *.c nested e!
删除自动命令
使用以下命令,可以删除所有自动命令:
c
:autocmd!
注意:此操作也将删除插件所定义的自动命令,请谨慎操作。
使用以下命令,可以删除指定组的自动命令:
cpp
:autocmd! group
在命令中指定组、事件和匹配模式,可以删除特定的自动命令:
cpp
autocmd! Unfocussed FocusLost *.txt
在命令中使用特殊字符"*"来指代所有事件或文件。例如以下命令,将删除Unfocussed组中所有针对txt文件的自动命令:
cpp
autocmd! Unfocussed * *.txt
在命令中忽略文件匹配模式,那么所有针对指定事件的针对命令都将被删除。例如以下命令,将删除Unfocussed组在所有针对FocusLost事件的自动命令:
csharp
autocmd! Unfocussed FocusLost
自动命令组
通过:augroup命令,可以将多个相关联的自动命令分组管理,以便于按组来查看或删除自动命令。例如以下命令,将C语言开发的相关自动命令,组织在"cprogram"组内:
cpp
:augroup cprograms
: autocmd!
: autocmd FileReadPost *.c :set cindent
: autocmd FileReadPost *.cpp :set cindent
:augroup END
如果我们针对同样的文件和同样的事件定义了多条自动命令,那么当满足触发条件时将分别执行多条自动命令。因此,建议在自动命令组的开头增加:autocmd!命令,以确保没有重复的自动命令存在。
您可以使用以下命令,获得自动命令组的帮助信息:
cpp
:help :augroup
自动命令选项
通过eventignore选项,可以忽略指定的事件,而不触发自动命令。例如使用以下命令,将忽略进入窗口和离开窗口的事件:
cpp
:set eventignore=WinEnter,WinLeave
如果希望忽略所有事件,那么可以使用以下设置:
cpp
:set eventignore=all
命令小结:
:autocmd! | 删除自动命令 |
:augroup | 定义自动命令组 |
:set eventignore | 设置忽略的事件 |
推荐阅读 :
https://yyq123.github.io/learn-vim/learn-vi-49-01-autocmd.html