主动命令 autocommand
回顾
上次咱们钻研的是外部命令grep
- 能够在vim中应用grep
- 搜寻的后果进入了列表
- 能够关上、遍历、跳转、敞开这个列表
- 也能够给列表中的匹配行或者每个文件执行命令
到此为止学了很多的命令
- 有外部的也有内部的
- 有的在命令行模式外面执行
- 还有的映射到一组键盘在失常模式下执行
- 然而都须要按下些什么按键能力反对
- 是否什么都不按主动就执行呢?
主动命令autocmd
- 在~/.vim/ftplugin(以后用户的插件目录)编辑插件文件
ftplugin中
- ft代表filetype
- plugin代表插件
mkdir -p ~/.vim/ftpluginsudo vi ~/.vim/ftplugin/log.vim
- 定义函数
function DateInsert() $delete read !dateendfunction
$delete
- 把原来的最初一行的日期删除掉
read !date
- 读取以后日期
- 并且写到最初一行
尝试调用
新建并关上log文件
- vi a.log
调用函数
:call DateInsert()
- 然而他如同不意识log文件一样
:function
中没有DateInsert():function DateInsert
设置filetype文件类型
- Q进入Ex模式
:filetype
- 查看文件类型检测状况
:set filetype=log
- 强制设置文件类型为log
:function DateInsert
- 察看DateInsert函数
- 能够找到了定义的函数了
- 是否能够调用呢?
:call DateInsert()
- 调用DateInsert()
:visual
- 回到编辑模式
- 然而每次都要手动设置filetype么?
- 这颗太麻烦了
- 是否自动检测呢?
自动检测文件类型filetype
查问帮忙
:h filetype
mkdir ~/.vim/ftdetect
sudo vi ~/.vim/ftdetect/log.vim
- ft代表filetype
- detect 代表文件自动检测
- 在文件外面写上
au BufRead,BufNewFile *.log set filetype=log
vi a.log
- 检测胜利
:call DateInsert()
- 函数调用胜利
- 我想把这个函数做成一个命令能够么?
制作命令
:nnoremap Di :call DateInsert()<CR>
nnoremap
n
normal 失常模式noremap
不再递归映射
- Di 指定的命令Command
- :call DateInsert() 调用函数
<CR>
carriage 回车
在normal模式下顺次按下
Di
- 能够用
- 再次
Di
能够刷新工夫 - 我想保留的时候主动调用能够么?
主动命令
:autocmd BufWritePre *.log call DateInsert()
autocmd
是命令的名字- 作用是增加主动命令
BufWritePre
是{events} 是触发条件Buf
指的是以后缓存bufferWrite
指的是写以后缓存Pre
指的是在写以后缓存之前
*.log
是 {file_pattern} 是文件模式- 目前文件模式为
*.log
- 目前文件模式为
call DateInsert()
是{cmd}- 对应具体执行的命令
:wq
cat a.log
- 最新的工夫曾经写在最初一行了
- 不过这个主动命令最好写在filetype的插件外面
- 这样主动命令就被定义到主动插件外面了
删除主动命令
:autocmd
- 能够查看所有的主动命令autocmd
:autocmd! FileWritePre *.log
- 留神那个叹号是否定的意思
- 把他定义为啥都没有
- 也就删除了
配置插件
vi ~/.vim/ftplugin/log.vim
:autocmd BufWritePre *.log call DateInsert()
- 为什么强调
*.log
呢 - 因为如果{file_pattern}是
*.*
的话 - 一旦关上了
log
文件 - 保留任何其余文件时都会执行
DateInsert()
了
- 为什么强调
echo "i am a log!"set filetype=log source ~/.vim/ftplugin/log.vimautocmd BufWritePre *.log call DateInsert()
查看帮忙
:h autocmd
- {events} 具体的触发事件
- {pattern} 文件模式
- {group} 成组 主动命令成组并命名 可省
- group 应该如何了解?
成组主动命令
- 成组是可选的
- 能够成组也能够不成组
- 这是绕口令么?
- 咱们来看看
augroup cprograms autocmd BufReadPost *.c *.h :set sw=4 sts=4 autocmd BufReadPost *.cpp :set sw=3 sts=3augroup END
下面说的是在读取.c、.h 之后
- 主动设置缩进宽度为4
在读取.cpp之后
- 主动设置缩进宽度为3
- 总而言之这两主动命令成为了一个组叫做cprograms
- 也能够写成
autocmd cprograms BufReadPost *.c *.h :set sw=4 sts=4 autocmd cprograms BufReadPost *.cpp :set sw=3 sts=3
- 上面这样能够删除组中所有的主动命令
:autocmd! cprograms
触发事件events
:autocmd BufReadPost *.gsm set filetype=asm
BufReadPost
是读取之后set filetype=asm
- 把gsm文件的文件格式filetype设置为asm
- gsm是gnu的assemble language
:autocmd Filetype text source ~/.vim/abbrevs.vim
Filetype text
- 是检测到文件类型为文本的时候
vi a.txt
能够触发Filetype text
source ~/.vim/abbrevs.vim
- 加载一些缩写
:autocmd BufNewFile *.[ch] 0read ~/sktletons/skel.c
BufNewFile *.[ch]
BufNewFile
新建缓存文件的时候*.[ch]
- 文件类型对应
*.c或者*.h
- 文件类型对应
0read ~/sktletons/skel.c
- 加载c一个骨架文件作为框架
- 而后添皮加肉
文件模式patterns
通配符wild character
*任意多个字符或数字
- *.c
- *.h
?一个字母
- D???.c
.
- 对应一个点dot
[]或者关系
- *.[ch]
{}或者关系
- a{b,c}
- 对应ab或ac
/
- 在对应门路中应用,比方:
- ~/.vim/ftplugin/*
- /home/oeasy/*.txt
主动命令的嵌套
- 一般来说主动命令的执行后果不会触发另一个主动命令
- 然而,如果你偏要触发
- 能够加上 nested
:autocmd FileChangedShell * nested edit
- 比方你关上了文件时触发了主动命令
- 主动命令做出了一些批改
- 这些批改就也会触发这个事件
应用文件名和扩展名
touch oeasy.txt oeasy.txt.new
- 新建两个文件
vi
:echo expand("%:t")
- 输入文件名
- 因为当初啥都没有所以啥都没输入
:e oeasy.txt
- 关上oeasy.txt进入缓存buffer
:echo expand("%:t")
- 输入以后文件名
:echo "hello i am " . expand("%:t")
- 输入一句话
autocmd BufReadPost * echo "hello i am " . expand("%:t")
- 定义主动命令
- 读取任何文件格式的文件之后
- 输入hello 和 以后文件名
:h expand
- 显示
hello i am eval.txt
- 显示
- 胜利
强制触发
:doautocmd BufReadPost oeasy.txt
- 尽管后没有关上
oeasy.txt
- 然而他强制执行了
BufReadPost oeasy.txt
对应的主动命令autocmd
- 尽管后没有关上
- 这样的话我能够在读取oeasy.txt.new的时候
- 而后显示出oeasy.txt么?
:autocmd BufReadPost *.new echo "hhh " . expand("<afile>:r")
- 先退出vim
执行其余的主动命令
- 从新关上vim
输出
:autocmd BufReadPost *.txt echo "hello i am txt:" . expand("%:t")
- 定义对于txt文件读取之后的主动命令
- 而后关上txt文件和非txt文件
- 关上或切换时会有相应的显示
- 而非txt文件不会有显示
- 此时关上oeasy.txt.new没有任何提醒
:autocmd BufReadPost *.new execute "doautocmd BufReadPost " . expand("<afile>:r")
autocmd BufReadPost *.new
- 定义
*.new
关上之后对应的主动命令
- 定义
excute "doautocmd BufReadPost " . expand("<afile>:r")
- 执行 "doautocmd BufReadPost " . expand("<afile>:r")
如果咱们从新关上
oeasy.txt.new
或者切换buffer的时候- 强制执行
oeasy.txt
关上后的主动命令 - 也就是
execute "doautocmd BufReadPost oeasy.txt"
- 强制执行
执行失常模式命令
- 方才执行的都是命令行模式的命令
- 如果我想执行失常模式的命令应该如何呢?
:autocmd BufReadPost *.log normal G
- 读取
*.log
的时候 - normal G 在失常模式下执行G
- 跳到最初一行,查看最新的日志
- 读取
- 那么能够主动命令能够进入插入模式么?
normal
进入失常模式,在失常模式下- i进入插入模式 esc退出
- :进入命令模式 esc退出
- /进入搜寻模式 esc退出
:autocmd BufReadPost *.txt execute "normal ggONew entry:\<Esc>" | 1read !date
autocmd BufReadPost *.txt
- 制作读取txt文件后对应主动命令
excute "normal ggONew entry:\<Esc>" | 1read !date
- 执行
normal ggONew entry:\<Esc>
在第一行写字 |
而后执行1read !date
在第二行写日期
- 执行
- 咱们最初来看看曾经写好的一些autocmd
vim的零碎文件夹
咱们之前都是在用户的vim文件夹进行配置
- 用户的vim文件夹只能配置以后用户的vim
当初咱们去零碎的vim文件夹看看具体的配置
- 这样咱们就能够给所有用户配置vim了
零碎的vim的文件夹在
/usr/share/vim/vim81
- 基本上配置都在这里实现
其中有一些缩写
- au autocmd
- exe execute
总结
- 这个主动命令还是很不便的
- 关上时、保留时就会有主动执行的操作
主动命令有这么几大元素
{event}
触发事件{pattern}
文件模式{cmd}
具体执行命令{augroup}
命令组
- 主动命令能够新建、删除、列表、查问
- 还能够强制执行
有这个咱们能够
- 针对每种不同的文件的类型
- 定义相应的触发事件
- 而后执行各种各样的命令
- 不便操作
不过对于文件类型的高亮显示还是没有讲的特地分明
- 为什么
public
在java
文件外面就能够扭转色彩呢??
- 为什么
- 下次再说!