星期一, 十二月 23, 2019

VIM学习笔记 自动命令-实例(autocmd-examples)

以下实例,将为您使用自动命令提高编辑效率提供灵感。关于自动命令的创建和管理,请参阅自动命令(autocmd)章节。

例如以下自动命令,将在离开Vim编辑器时,自动保存文件:
autocmd FocusLost * :wa

根据文件类型执行自动命令

可以根据文件类型,执行特定命令。例如以下自动命令,将删除php文件行尾的空格:
autocmd BufEnter *.php :%s/[ \t\r]\+$//e
可以根据文件类型,载入相关插件:
autocmd Filetype html,xml,xsl source $VIM/vimfile/plugin/closetag.vim
可以根据文件类型,设置键盘映射
autocmd bufenter *.tex map <F1> :!latex %<CR>
可以根据文件类型,设置不同的选项:
autocmd FileType ruby setlocal ts=2 sts=2 sw=2 expandtab

自动创建目录

定义以下自动命令,将在保存文件时,检查所指定的目录是否存在:
augroup vimrc-auto-mkdir
  autocmd!
  autocmd BufWritePre * call s:auto_mkdir(expand('<afile>:p:h'), v:cmdbang)
  function! s:auto_mkdir(dir, force)
    if !isdirectory(a:dir)
          \   && (a:force
          \       || input("'" . a:dir . "' does not exist. Create? [y/N]") =~? '^y\%[es]$')
      call mkdir(iconv(a:dir, &encoding, &termencoding), 'p')
    endif
  endfunction
augroup END

如果使用:w命令保存文件时,引用了不存在的目录,那么将显示以下询问信息:
'XXXXX' does not exist. Create? [y/N]
你可以输入“y”,以自动创建目录并保存文件。
如果使用:w!命令保存文件时,引用了不存在的目录,那么将不会显示询问信息,而直接创建目录并保存文件。

自动应用配置文件

在保存vimrc配置文件时,将自动重载并生效变更之后设置,而免去了关闭并重新打开Vim的手工操作:
augroup Reload_Vimrc        " Group name.  Always use a unique name!
    autocmd!                " Clear any preexisting autocommands from this group
    autocmd! BufWritePost $MYVIMRC source % | echom "Reloaded " . $MYVIMRC | redraw
    autocmd! BufWritePost $MYGVIMRC if has('gui_running') | so % | echom "Reloaded " . $MYGVIMRC | endif | redraw
augroup END

自动更新时间戳

利用以下自动命令,将在保存文件时,自动更新文件中的时间戳信息。首先将查找以“This file last updated:”开头的行,然后将“:”之后的时间替换为当前时间。
This file last updated: 12/23/2019 4:05:10 PM

function! UpdateTimestamp ()
  '[,']s/^This file last updated: \zs.*/\= strftime("%c") /
endfunction

augroup TimeStamping
  autocmd!
  autocmd BufWritePre,FileWritePre,FileAppendPre * :call UpdateTimestamp()
augroup END

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

星期四, 十二月 19, 2019

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

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

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

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

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

:call DateInsert()

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

:autocmd FileWritePre * :callDateInsert()<CR>

定义自动命令

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

: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设置任何选项之后
启动
退出
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<上一篇 | 目录 下一篇>

星期二, 十二月 10, 2019

VIM学习笔记 语法高亮度-日志文件(Syntax-Logfile)

在系统排错过程中,常常需要在日志文件里大海捞针。面对数量巨大的繁杂信息,如何快速准确地找到线索,就显得格外重要了。

利用语法高亮度(Syntax),可以突出显示重要的信息,比如:

  • 包含“Error”和“Fail”等关键词的报错信息;
  • 日期、网址、文件名等对象;
  • 数字、字符串、操作符等元素。

定义语法高亮度

首先,定义需要着重显示的文本内容:

匹配指定的关键字:

syn keyword logLevelError error fail failure

匹配特定模式的字符串:

syn match logDate 'd{2}/d{2}/d{4}s*d{2}:d{2}:d{2}'

然后,定义如何显示特定的文本内容:

将以上定义的语法高亮组,链接到配色方案定义过的语法高亮组:

hi def link logLevelError ErrorMsg

也可以直接定义文本的显示色彩:

hi def logLevelError guifg=#ddddff guibg=#444444

配置语法高亮度

首先,将语法高亮文件,放置在以下目录:

Linux: $HOME/.vim/syntax

Windows: $HOME/vimfiles/syntax

然后,在vimrc配置文件中增加以下命令,以侦测.log为后缀名的日志文件并启用语法高亮度:

au BufNewFile,BufRead *.log setfiletype log

语法高亮度效果

Syntax_logfile

关于日志查看的一点想法

  • 对于动辄百兆的大型日志文件,Vim并非理想的工具。通常情况下:首先,利用tailgrep等命令,将日志文件截取为较小的片段;然后,再使用Vim进行细致地分析。
  • 过多的语法高亮度,不但会影响打开文件的速度,而且还会增加阅读的干扰。应该克制地使用视觉元素,仅仅突出显示最为关键的信息。比如,您可以在语法高亮文件中,注释掉关于日期和网址等元素的定义,而仅仅保留对于报错信息的突出显示。
  • 对于日志分析,并没有捷径。虽然vim-logreview等插件,可以移除日志文件中的正常统计输出,而仅仅保留报错信息。但异常事件通常并非孤立的单点问题,而其前后的上下文信息对于建立时间线和还原事件场景都有着极高的价值。对于大多数问题,并不能通过单一的报错信息,直接指向确定的解决方案。
  • 由此看来,利用语法高亮度来突出显示报错信息,然后小心厘清来龙去脉,算是现实可行的权宜之计吧?

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