共计 4433 个字符,预计需要花费 12 分钟才能阅读完成。
主动命令 autocommand
回顾
-
上次咱们钻研的是外部命令 grep
- 能够在 vim 中应用 grep
- 搜寻的后果进入了列表
- 能够关上、遍历、跳转、敞开这个列表
- 也能够给列表中的匹配行或者每个文件执行命令
-
到此为止学了很多的命令
- 有外部的也有内部的
- 有的在命令行模式外面执行
- 还有的映射到一组键盘在失常模式下执行
- 然而都须要按下些什么按键能力反对
- 是否什么都不按主动就执行呢?🤔
主动命令 autocmd
- 在~/.vim/ftplugin(以后用户的插件目录)编辑插件文件
-
ftplugin 中
- ft 代表 filetype
- plugin 代表插件
mkdir -p ~/.vim/ftplugin | |
sudo vi ~/.vim/ftplugin/log.vim |
- 定义函数
function DateInsert() | |
$delete | |
read !date | |
endfunction |
-
$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.vim | |
autocmd 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=3 | |
augroup 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
文件外面就能够扭转色彩呢??🤔
- 为什么
- 下次再说!