Vim技能修炼教程(2) - 语法高亮速成

    xiaoxiao2023-06-21  172

    语法高亮速成

    我们继续在人间修行Vim技能之旅。上一次我们学习了如何通过vundle安装插件,这次我们迅速向写插件的方向挺进。

    我们先学习一个最简单的语法高亮插件的写法。语法高亮基本上是由三部分组成:

    配色方案正则表达式配色方案和正则表达式的规则对应关系

    简单的三步法写语法高亮

    第一步,写匹配的正则表达式

    我们举个最简单的例子,以Android的log为例,Android的log格式如下:

    --------- beginning of system 05-05 17:55:48.909 I/ActivityManager( 2454): Start proc 15530:com.ss.android.article.lite:pushservice/u0a69 for service com.ss.android.article.lite/com.xiaomi.push.service.XMPushService 05-05 17:55:48.920 V/Build (15530): clr 05-05 17:55:48.933 D/CompatibilityInfo( 2454): mCompatibilityFlags - 0 05-05 17:55:48.933 D/CompatibilityInfo( 2454): applicationDensity - 640 05-05 17:55:48.933 D/CompatibilityInfo( 2454): applicationScale - 1.0

    从中可以看到,前面先是一个时间戳,然后是log的类型,接着是Tag,进程号和具体内容。

    最简单的做法,我们就只取log类型和后面的"/"这两个特征,正则表达式这样写:

    syn match LogF '\<F/.*' syn match LogE '\<E/.*' syn match LogW '\<W/.*' syn match LogI '\<I/.*' syn match LogD '\<D/.*' syn match LogV '\<V/.*'

    其中,'<'表示匹配一个单词的词首。详细信息可以通过:help \<来查询,在帮助的pattern.txt中。

    第二步,为场景配色

    下面,我们需要为这些匹配的场景定义颜色:有四种属性可以使用:

    ctermfg: 在终端时运行的前景色ctermbg: 终端时的背景色guifg: 图形界面的前景色guibg: 图形界面的背景色定义格式:hi def 配色名 {颜色列表}

    hi def是highlight default的缩写

    例:

    hi def LogF_color ctermfg=white guifg=white ctermbg=red guibg=red hi def LogE_color ctermfg=red guifg=red hi def LogW_color ctermfg=brown guifg=brown hi def LogI_color ctermfg=grey guifg=grey hi def LogD_color ctermfg=darkcyan guifg=darkcyan hi def LogV_color ctermfg=grey guifg=grey

    第三步,将配色和正则表达式映射在一起

    使用hi def link命令,将第一步和第二步的成果链接在一起就好了。

    hi def link LogF LogF_color hi def link LogE LogE_color hi def link LogW LogW_color hi def link LogI LogI_color hi def link LogD LogD_color hi def link LogV LogV_color

    注:上述代码引用自:https://github.com/serpent7776/vim-logcat/blob/master/syntax/logcat.vim非作者原创,版权归原作者所有。

    更复杂一点的例子

    看了最简单的一个实现,我们当然还可以做得更复杂一些:我们参考一个更复杂一些的例子:https://github.com/gburca/vim-logcat/blob/master/syntax/logcat.vim

    " Vim syntax file " Language: Android LogCat and aplogd log file syntax " Maintainer: Gabriel Burca <gburca dash vim at ebixio dot com> " " adb logcat -v time *:V " 06-09 14:36:00.000 V/AlarmManager( 1484): sending alarm {957ff72 type 3 *alarm*:android.intent.action.TIME_TICK} " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " " Or for aplogd logs (syntax group names end with '2'): " 06-08 16:17:56.101 566 566 E NEW_BHD : Open /sys/class/power_supply/gb_battery " 06-08 16:17:55.183 18677 20835 D ACDB-LOADER: ACDB -> ACDB_CMD_GET_AFE_COMMON_TABLE " 06-08 16:17:55.183 18677 20835 D : ACDBFILE_MGR:Read the devices count as zero, please check the acdb file if exists("b:current_syntax") finish endif ... syn match lcBegin display '^' nextgroup=lcDate " Example: " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " ^^^^^^ syn match lcDate '[0-1]\d-[0-3]\d ' \ nextgroup=lcTime " Example: " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " ^^^^^^^^^^^^^ syn match lcTime '[0-1]\d:[0-5]\d:[0-5]\d\.\d\d\d ' \ nextgroup=lcTag,lcThread2 " Example: " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " ^ syn match lcPriority '\(V\|D\|I\|W\|E\|F\)[\/ ]'me=e-1 \ containedin=lcTag nextgroup=lcTag2 " Must come after lcPriority so it has higher match priority syn match lcTagError 'E\/[[:alnum:]_-]\+' \ containedin=lcTag " Example: " 06-08 16:17:56.101 566 566 E NEW_BHD : Open /sys/class/power_supply/gb_battery syn match lcTagError2 'E [^:]\+:' \ nextgroup=lcMsgBody " The component may be empty in some cases " Example: " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " ^^^^^^ syn match lcComponent '\/[^[:space:](]\+'ms=s+1 \ containedin=lcTag " Example: " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " ^^^^^^^^^^ " 06-09 10:42:06.729 I/ ( 1484): Message with empty component " ^^^^^^^^^^ syn match lcTag '\w\/[^(]*\s*' \ nextgroup=lcThread contains=lcTagError,lcPriority,lcComponent,myTags " Example: " 06-08 16:17:55.183 18677 20835 D ACDB-LOADER: ACDB -> ACDB_CMD_GET_AFE_COMMON_TABLE " ^^^^^^^^^^^^ " 06-08 16:17:55.183 18677 20835 D : ACDBFILE_MGR:Read the devices count as zero, please check the acdb file " ^^^^^^^^^ syn match lcTag2 ' [^:]*\s*:' \ nextgroup=lcMsgBody contains=myTags " Example: " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " ^^^^^^^^ syn match lcThread '(\s*\d\+):'he=e-1 \ nextgroup=lcMsgBody contains=lcNumber " Example: " 06-08 16:17:55.183 18677 20835 D ACDB-LOADER: ACDB -> ACDB_CMD_GET_AFE_COMMON_TABLE " ^^^^^^^^^^^^ syn match lcThread2 '\s*\d\+\s\+\d\+ ' \ nextgroup=lcPriority,lcTagError2 contains=lcNumber " Example: " 06-09 10:42:06.729 I/chatty ( 1484): uid=1000(system) Binder:1484_5 expire 1 line " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ syn match lcMsgBody contained ' .*' \ contains=myKeywords syn match lcNumber contained '0x[0-9a-fA-F]*\|\[<[0-9a-f]\+>\]\|\<\d[0-9a-fA-F]*' hi def link lcDate Comment hi def link lcTime SpecialComment hi def link lcTag Statement hi def link lcTag2 Statement hi def link lcPriority Identifier hi def link lcTagError Error hi def link lcTagError2 Error hi def link lcComponent Normal hi def link lcThread Special hi def link lcThread2 Special hi def link lcMsgBody Normal hi def link lcNumber Number hi def link myTags Function hi def link myKeywords Function

    与上一个完全自定义颜色不同,这位作者直接将正则表达式映射到语言的预定义配色方案中。比如Comment是注释,Statement是语句,Identifier是标识符等等。具体可以通过:help syntax来学习,我们后面晋阶上仙的教程里也会有详细介绍。总而言之,这个的正则表达式更复杂了,但是基本原理还是一样的。

    例三

    下面我们再趁热打铁,来看一个更复杂,也更人性化的例子:https://github.com/thinca/vim-logcat/blob/master/syntax/logcat.vim

    我们来看下面一段,根据背景是不是暗的配色而设计两套配色方案,非常贴心:

    function! s:define_color() if &background is 'dark' highlight default logcatLevelVerbose guifg=Gray ctermfg=Gray highlight default logcatLevelDebug guifg=Cyan ctermfg=Cyan highlight default logcatLevelInfo guifg=Green ctermfg=Green highlight default logcatLevelWarning guifg=Yellow ctermfg=Yellow highlight default logcatLevelError guifg=Red ctermfg=Red else highlight default logcatLevelVerbose guifg=DarkGray ctermfg=DarkGray highlight default logcatLevelDebug guifg=DarkCyan ctermfg=DarkCyan highlight default logcatLevelInfo guifg=DarkGreen ctermfg=DarkGreen highlight default logcatLevelWarning guifg=DarkYellow ctermfg=DarkYellow highlight default logcatLevelError guifg=DarkRed ctermfg=DarkRed endif highlight default logcatLevelFatal guifg=White ctermfg=White guibg=Red ctermbg=Red endfunction

    小结

    小结一下,我们这节只学习三个命令:

    syntax match: 正则表达式和场景匹配highlight default: 为场景定义配色highlight link: 将上两者联系在一起,也可以链接到预定义的一些标准配色方案上 相关资源:敏捷开发V1.0.pptx
    最新回复(0)