自动命令 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指的是当前缓存buffer
      • Write指的是写当前缓存
      • 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} 命令组
  • 自动命令可以新建、删除、列表、查询
  • 还可以强制执行
  • 有这个我们可以

    • 针对每种不同的文件的类型
    • 定义相应的触发事件
    • 然后执行各种各样的命令
    • 方便操作
  • 不过关于文件类型的高亮显示还是没有讲的特别清楚

    • 为什么publicjava文件里面就可以改变颜色呢??
  • 下次再说!

oeasy教您玩转vim - 88 - # 自动命令autocmd的更多相关文章

  1. oeasy教您玩转vim - 56 - # 字符可视化模式

    ​ 可视化编辑 回忆上节课内容 我们学习了关于模式匹配中使用参数 单个参数 :%s/<h2>\(.*\)</h2>/ - \1/g 多个参数 :%s/<img src=\ ...

  2. oeasy教您玩转vim - 57 - # 行可视化

    ​ 可视化编辑 回忆上节课内容 上次我们了解到可视模式 其实可视化对应三种子模式 字符可视模式 v 行可视模式 大写V 块可视模式ctrl+v 我们先来了解字符可视化模式 快捷键 v 可配合各种mot ...

  3. oeasy教您玩转vim - 53 - # 批量替换

    查找细节 回忆上节课内容 我们温习了关于搜索的相关内容 /正向,?反向 n保持方向,N改变方向 可以设置 是否忽略大写小写 是否从头开始查找 是否高亮显示 还有一些正则表达式的使用方法 行头行尾 ^$ ...

  4. oeasy教您玩转linux010203显示logo

    我们来回顾一下 上一部分我们都讲了什么?

  5. oeasy 教您玩转linux010101查看内核uname

    linux([?l?n?ks]) 是什么????? 咱们这次讲点什么呢?这次咱们讲讲这个 linux([?l?n?ks]),什么是 linux([?l?n?ks])呢?这linux([?l?n?ks] ...

  6. oeasy教您玩转linux010202软件包管理apt

    顾一下 上一部分我们都讲了什么?

  7. oeasy教您玩转linux010201持续输出yes

    我们来回顾一下 上一部分我们都讲了什么?

  8. oeasy教您玩转linux010108到底哪个which

    到底哪个which 回忆上次内容 我们上次讲了查找命令位置whereis 我想找到whereis的位置怎么办?

  9. oeasy教您玩转python - 006 - # hello world

    ​ Hello World! 回忆上次内容 python3 的程序是一个 5.3M 的可执行文件 python3 里面全都是 cpu 指令 可以执行的那种指令 我们可以把指令对应的汇编找到 objdu ...

  10. oeasy教您玩转linux-010110内容回顾

    我们来回顾一下 我们都讲了什么?

随机推荐

  1. 模拟重装Kubernetes(k8s)集群:删除k8s集群然后重装

    目录 一.系统环境 二.前言 三.重装Kubernetes集群 3.1 环境介绍 3.2 删除k8s所有节点(node) 3.3 kubeadm初始化 3.4 添加worker节点到k8s集群 3.5 ...

  2. uni-app前端图表组件库,折线图横屏android失败的解决办法

    网址:https://www.ucharts.cn/v2/#/demo/index,需要登录,微信就可以 我在使用折现图时,业务需要把曲线图在点击全屏时横屏全屏显示.就做个全屏页面,点击后,把opti ...

  3. JS+DOM简要笔记

    js官方文档: https://www.w3school.com.cn/js/index.asp 简单理解:html是内容,css是控制样式,js是行为. 1,js弱类型特点 JavaScript 是 ...

  4. [brief]虚拟机安装UbuntuServer

    1.下载Ubuntu--Server镜像官网点击 2.Vmware15.x配置 2G /boot 4G swap(一倍或两倍于分配内存量) rest / or /+/home 3.terminal下安 ...

  5. 鸿蒙HarmonyOS实战-Web组件(请求响应和页面调试)

    前言 请求响应是指客户端发送请求给服务器,服务器接收到请求后返回的响应.响应包含了服务器处理请求的结果,并将结果返回给客户端. 页面调试是指在开发过程中,通过调试工具分析页面的运行状况,查找问题和修复 ...

  6. GIT文件上传演示

    Be Written By Handat.憨大头 注:以下内容默认你已经做好了git工具的用户账户配置. (1)创建Gitee线上代码仓库,HTTPS协议地址就是仓库地址,如例https://gite ...

  7. uniapp 上拉加载下拉刷新

    page.json中配置"enablePullDownRefresh": true //单个页面修改刷新按钮的颜色 "app-plus": { "ti ...

  8. docker ——网络配置和管理

    docker网络基础 了解docker网络 两种docker网络 单主机与多主机的docker网络 网络驱动 网络驱动 介绍 bridge 桥接网络,这是默认的网络驱动程序 host 主机网络 ove ...

  9. 讲课 PPT 公开啦

    目前限于时间原因,只在 Github Pages 上托管了. 之后有时间会托管到 pythonanywhere 上,因为 Github Pages 是在太慢了.

  10. Windows下cmd命令行sftp上传至Linux服务器

    1.Windows+R进入运行 2.输入cmd,进入命令行 3.命令建立连接 sftp 用户名@ip地址 例如: 输入密码,即可建立连接 上传方式: 1)直接拖动文件到命令行窗口,可以直接显示该文件的 ...