Vimscript 高級語法高亮

2018-02-24 16:02 更新

目前我們已經(jīng)為Potion文件實(shí)現(xiàn)了簡單的關(guān)鍵字和函數(shù)的語法高亮。

如果沒有做上一章的練習(xí),你需要回去完成。我將假設(shè)你做了練習(xí)。

事實(shí)上,你應(yīng)該回去完成你跳過的_任何_練習(xí)。即使你覺得你不需要,為了更好的學(xué)習(xí)效果, 你都得把它們完成了。請?jiān)谶@一點(diǎn)上相信我。

高亮注釋

接下來我們需要高亮Potion的一個(gè)重要組成部分——注釋。 問題是,Potion的注釋以#開頭,而#并不在iskeyword里。

如果不知道什么是iskeyword,你沒有認(rèn)真聽講?;厝ゲ?em>完成那該死的練習(xí)。 在寫每一章的內(nèi)容時(shí),我不會(huì)把無意義的粗重活丟給你。你_真的_需要完成它們來跟上本書的進(jìn)度。

因?yàn)?code>#不是一個(gè)keyword字符,我們需要使用正則表達(dá)式來匹配它(以及接下來的注釋)。 我們將用syntax match代替syntax keyword。在你的syntax文件中加入下面幾行:

syntax match potionComment "\v#.*$"
highlight link potionComment Comment

我不會(huì)再嘮叨要把它們放到文件的哪里。你已經(jīng)是個(gè)程序猿了:由你自己判斷。

關(guān)閉并重新打開factorial.pn。在文件的某處添加一個(gè)注釋,你將看到它被當(dāng)作注釋高亮了。

第二行是簡單的:它告訴Vim高亮potionComment語法類型組里的任何東西為Comment

第一行有點(diǎn)新東西。我們使用syntax match來告訴Vim用_正則表達(dá)式_而不是關(guān)鍵詞來匹配。

注意正則表達(dá)式以\v開頭,表示使用"very magic"模式。 如果你不太清楚,重讀關(guān)于基本正則表達(dá)式的那一章。(譯注:第31章)

當(dāng)前狀況下,"very magic"模式不是必須的。 但將來我們可能會(huì)改變這個(gè)正則表達(dá)式,然后苦思冥想為何它不工作了, 所以我建議總是使用"very magic"來保證一致性。

至于正則表達(dá)式的功能,非常簡單:匹配以#開頭的注釋,包括以此開始到行末的所有字符。

如果你需要重新喚起對正則表達(dá)式的記憶,你應(yīng)該看一下 Zed Shaw的Learn Regex the Hard Way。

高亮運(yùn)算符

另一個(gè)需要正則表達(dá)式來高亮的部分是運(yùn)算符。在你的syntax文件中加入下列內(nèi)容:

syntax match potionOperator "\v\*"
syntax match potionOperator "\v/"
syntax match potionOperator "\v\+"
syntax match potionOperator "\v-"
syntax match potionOperator "\v\?"
syntax match potionOperator "\v\*\="
syntax match potionOperator "\v/\="
syntax match potionOperator "\v\+\="
syntax match potionOperator "\v-\="

highlight link potionOperator Operator

關(guān)閉并重新打開factorial.pn。注意到階乘函數(shù)的*=現(xiàn)在被高亮了。

你可能首先注意到,我把每個(gè)正則表達(dá)式獨(dú)立成一行而不是像對關(guān)鍵字一樣分成組。 這是因?yàn)?code>syntax match_不_支持在一行里放多個(gè)組。

你應(yīng)該也注意到每個(gè)正則表達(dá)式都以\v開頭,即使并不是必須的。 在寫Vimscript時(shí),我希望保持正則表達(dá)式的一致性,即使這樣做需要多打幾個(gè)符號(hào)。

你可能會(huì)奇怪,為什么我不用類似于"\v-\=?"的正則表達(dá)式來同時(shí)匹配-以及-=。 你想要的話也可以這么做。它會(huì)正常工作。 我只是堅(jiān)持認(rèn)為--=是不同的運(yùn)算符,所以把它們放到不同行里。

把每個(gè)運(yùn)算符放在單獨(dú)的匹配中,簡化了正則表達(dá)式,代價(jià)是輸入了額外的字符。 我喜歡這么做,但你可能不這么認(rèn)為。你自己決定吧。

我也沒有把=定義成一個(gè)運(yùn)算符。我們等會(huì)會(huì)這么做,但我希望暫時(shí)先不這樣做,這樣就能給你考上一題了。

因?yàn)榉珠_了--=的正則表達(dá)式,我不得不在定義-_之后_定義-=!

如果以相反的順序定義,并在Potion文件里使用-=,Vim將匹配-(當(dāng)然,同時(shí)也高亮它), 剩下=等待匹配。這意味著在構(gòu)建syntax match組時(shí),每個(gè)組"消耗"的文本片段在之后不能被匹配到。

這講得太籠統(tǒng)了,但我暫時(shí)并不打算糾結(jié)于細(xì)節(jié)。 總之,你應(yīng)該在匹配較小的組之后匹配較大的組,因?yàn)樵赺之后_定義的組優(yōu)先于在_之前_定義的組。

讓我們繼續(xù)并添加=作為運(yùn)算符?,F(xiàn)在請聽題:

syntax match potionOperator "\v\="

花一點(diǎn)時(shí)間想想你應(yīng)該把它放在syntax文件的哪個(gè)位置。如果你需要提示,重讀前幾章。

練習(xí)

閱讀:help syn-match.

閱讀:help syn-priority.

在例子中,我們沒有把:當(dāng)作運(yùn)算符。閱讀Potion文檔并審慎地決定是否把:當(dāng)作一個(gè)運(yùn)算符。 如果你決定這么做,把它加到syntax文件中。

同樣考慮./

增加一個(gè)高亮數(shù)字的語法類型分組potionNumber。鏈接它到高亮組Number。 不要忘了Potion支持2,0xffaf,123.23,1e-21.9956e+2這幾種形式。 記得在處理邊際狀態(tài)的花費(fèi)的時(shí)間和這些邊際狀態(tài)出現(xiàn)的次數(shù)之間取得平衡。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)