本身写VIM语法高亮插件

实习以后发现,一切代码活动都局限在一个终端界面了。因为一些安全缘由和开发环境的方便,开发都是经过远程ssh到开发机上开发,天然也就只有终端界面了。VNC由于安全缘由不让用,因此就别妄想使用Clion等IDE来开发了。在这样的背景下,人们大多使用VIM或者EMACS等编辑器来开发。html

在调试过程当中,服务端日志是一个重要的参考依据。可是这类文本并非某种编程语言,一般查阅的时候是没有语法高亮的,并且为了对grep命令友好,一般会将一条日志打在一行里,这就使得日志信息很是密集,分辩关键信息的时候很是不方便。因而我便有了这样一个想法,编写VIM插件,对日志中的关键信息如时间戳、代码行号、错误码进行语法高亮。正则表达式

为了叙述的方便,咱们的目标是为下面这段日志进行高亮,将日志级别、时间戳、代码行号标识出来。编程

[ERROR][2017-10-01 08:08:08][example.go:231]Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed diam eget risus varius blandit sit amet non magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
[DEBUG][2017-10-01 08:08:10][example.go:233]Lorem ipsum dolor sit amet
[INFO][2017-10-01 08:09:09][example.go:2333]Lorem ipsum dolor sit amet

语法高亮插件

语法高亮插件须要两个.vim文件。一个是语法检测文件(ftdetect),这是为了让VIM可以将指定语法应用于指定后缀的文件。一个是语法文件(syntax),这里定义了高亮的语法和着色方案。vim

插件的目录结构以下:安全

/Users/zhuangqh/.vim
├── ftdetect
│   └── log.vim
└── syntax
    └── log.vim

这些文件在类UNIX系统上要放到$HOME/.vim目录下,Windows系统是$HOME/vimfiles/下。ssh

语法检测

当buffer读取或建立时,将.log后缀的文件类型设置为log,以后使用log类型的语法高亮方案进行着色。编程语言

" ftdetect/log.vim
au BufNewFile,BufRead *.log set filetype=log

语法高亮

这是文本的重点,该文件告诉VIM该怎么着色。编辑器

关键字高亮

syn keyword ${group} ${keyword}

大多数编程语言都有关键字。规则设置的时候,先给他一个组名,后面再接着一些关键字,以后再根据这个组名设置颜色。关键字高亮的匹配优先级是最高的,若是有其它高亮规则匹配上了也会按关键字的规则来高亮。.net

这个规则对咱们此次任务没什么用,由于咱们只想高亮日志开头的那个特定的ERROR字样,存在上下文,实际上并非关键字。插件

匹配字高亮

syn match ${name} ${pattern}

这个命令提供了一种强大的匹配方法,用正则表达式来匹配。咱们能够用来匹配咱们的时间戳,如:syn match logDate '\d\{4}-\d\d-\d\d'

高亮嵌套

对某个匹配的字符串高亮以后,对子字符应用不一样的规则。

好比上述日志中的代码行号 example2.go:233,咱们先总体匹配了这个模式,而后但愿行号能有不同的颜色。这能够理解成匹配的上下文,规则只在指定上下文中有效。

syn match logFile '\w*\.go:\d*' contains=logLineNum
syn match logLineNum '\d*' contained

contains告诉VIM这个token会包含其余哪些token。contained告诉VIM,只有在被其余token包含时,该规则才有效。

匹配偏移

在高亮行号时,\d*规则会将全部的数字高亮,而事实上,只有冒号右边的数字才是行号,这就要用到匹配偏移的规则了。

syn match logLineNum ':\d*'ms=s+1 contained

匹配偏移用来调整实际匹配的值。ms(me)表示的是实际匹配的起始(终止)下标,s(e)表示的是原匹配字符的起始(终止)下标。咱们用:\d*匹配后,将下标向右调整一位便可。

记得偏移命令要紧跟模式项,不然会报错。

区域高亮

syn region ${name} start=${pattern} end=${pattern} skip=${pattern}

区域匹配最多见的是匹配一个字符串,用引号包裹的字符串,能够经过skip来跳过转义字符如\"

在咱们的日志高亮任务里,想匹配的是包含特定token的中括号,咱们只高亮中括号,其余的交由其余规则来匹配。

syn region logBlock matchgroup=logParen start=/\[/ end=/\]/ fold

配色

hi ${name} ctermfg=${color}

为前面定义的语法token设定着色样式,ctermfg是彩色终端的前景色,其余选项详见:highlight

结果

把全部规则集结起来以下:

if exists("b:current_syntax")
  finish
endif

syn match logLevelError 'ERROR' contained
syn match logLevelDebug 'DEBUG' contained
syn match logLevelInfo 'INFO' contained

syn match logFile '\w*\.go:\d*' contains=logLineNum
syn match logLineNum ':\d*'ms=s+1 contained

syn match logDate '\d\{4}-\d\d-\d\d' contained
syn match logTime '\d\d:\d\d:\d\d' contained
syn region logBlock matchgroup=logParen start=/\[/ end=/\]/ fold
 \ contains=logLevelError,logLevelDebug,logLevelInfo,logFile,logDate,logTime

hi logLevelError ctermfg=red
hi logLevelDebug ctermfg=yellow
hi logLevelInfo ctermfg=green
hi logFile ctermfg=yellow
hi logLineNum ctermfg=blue
hi logDate ctermfg=yellow
hi logTime ctermfg=blue
hi logBlock ctermfg=white
hi logParen ctermfg=grey

let b:current_syntax = "log"

参考资料

相关文章
相关标签/搜索