Vim技能修煉教程(2) - 語法高亮速成

語法高亮速成

我們繼續(xù)在人間修行Vim技能之旅哗戈。上一次我們學(xué)習(xí)了如何通過vundle安裝插件,這次我們迅速向?qū)懖寮姆较蛲M(jìn)。

我們先學(xué)習(xí)一個(gè)最簡(jiǎn)單的語法高亮插件的寫法淆党。
語法高亮基本上是由三部分組成:

  • 配色方案
  • 正則表達(dá)式
  • 配色方案和正則表達(dá)式的規(guī)則對(duì)應(yīng)關(guān)系

簡(jiǎn)單的三步法寫語法高亮

第一步,寫匹配的正則表達(dá)式

我們舉個(gè)最簡(jiǎn)單的例子讶凉,以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

從中可以看到,前面先是一個(gè)時(shí)間戳懂讯,然后是log的類型荷憋,接著是Tag,進(jìn)程號(hào)和具體內(nèi)容褐望。

最簡(jiǎn)單的做法勒庄,我們就只取log類型和后面的"/"這兩個(gè)特征串前,正則表達(dá)式這樣寫:

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

其中,'<'表示匹配一個(gè)單詞的詞首锅铅。詳細(xì)信息可以通過:help \<來查詢酪呻,在幫助的pattern.txt中。

第二步盐须,為場(chǎng)景配色

下面玩荠,我們需要為這些匹配的場(chǎng)景定義顏色:
有四種屬性可以使用:

  • ctermfg: 在終端時(shí)運(yùn)行的前景色
  • ctermbg: 終端時(shí)的背景色
  • 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

第三步,將配色和正則表達(dá)式映射在一起

使用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
非作者原創(chuàng),版權(quán)歸原作者所有塑径。

更復(fù)雜一點(diǎn)的例子

看了最簡(jiǎn)單的一個(gè)實(shí)現(xiàn)女坑,我們當(dāng)然還可以做得更復(fù)雜一些:
我們參考一個(gè)更復(fù)雜一些的例子: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

與上一個(gè)完全自定義顏色不同,這位作者直接將正則表達(dá)式映射到語言的預(yù)定義配色方案中统舀。比如Comment是注釋匆骗,Statement是語句,Identifier是標(biāo)識(shí)符等等誉简。具體可以通過:help syntax來學(xué)習(xí)碉就,我們后面晉階上仙的教程里也會(huì)有詳細(xì)介紹。
總而言之闷串,這個(gè)的正則表達(dá)式更復(fù)雜了瓮钥,但是基本原理還是一樣的。

例三

下面我們?cè)俪脽岽蜩F烹吵,來看一個(gè)更復(fù)雜碉熄,也更人性化的例子:https://github.com/thinca/vim-logcat/blob/master/syntax/logcat.vim

我們來看下面一段,根據(jù)背景是不是暗的配色而設(shè)計(jì)兩套配色方案肋拔,非常貼心:

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

小結(jié)

小結(jié)一下锈津,我們這節(jié)只學(xué)習(xí)三個(gè)命令:

  • syntax match: 正則表達(dá)式和場(chǎng)景匹配
  • highlight default: 為場(chǎng)景定義配色
  • highlight link: 將上兩者聯(lián)系在一起,也可以鏈接到預(yù)定義的一些標(biāo)準(zhǔn)配色方案上
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凉蜂,一起剝皮案震驚了整個(gè)濱河市一姿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌跃惫,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艾栋,死亡現(xiàn)場(chǎng)離奇詭異爆存,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蝗砾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門先较,熙熙樓的掌柜王于貴愁眉苦臉地迎上來携冤,“玉大人,你說我怎么就攤上這事闲勺≡兀” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵菜循,是天一觀的道長(zhǎng)翘地。 經(jīng)常有香客問我,道長(zhǎng)癌幕,這世上最難降的妖魔是什么衙耕? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮勺远,結(jié)果婚禮上橙喘,老公的妹妹穿的比我還像新娘。我一直安慰自己胶逢,他們只是感情好厅瞎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著初坠,像睡著了一般和簸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上某筐,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天比搭,我揣著相機(jī)與錄音,去河邊找鬼南誊。 笑死身诺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抄囚。 我是一名探鬼主播霉赡,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼幔托!你這毒婦竟也來了穴亏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤重挑,失蹤者是張志新(化名)和其女友劉穎嗓化,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谬哀,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刺覆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了史煎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谦屑。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驳糯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出氢橙,到底是詐尸還是另有隱情酝枢,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布悍手,位于F島的核電站帘睦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谓苟。R本人自食惡果不足惜官脓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涝焙。 院中可真熱鬧卑笨,春花似錦、人聲如沸仑撞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隧哮。三九已至桶良,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沮翔,已是汗流浹背陨帆。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留采蚀,地道東北人疲牵。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像榆鼠,于是被迫代替她去往敵國(guó)和親纲爸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容