實習以後發現,一切代碼活動都侷限在一個終端界面了。因爲一些安全緣由和開發環境的方便,開發都是經過遠程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"