在上一章里我們用Vim的`indent`折疊方式,在Potion文件中增加了一些快捷而骯臟的折疊。
打開`factorial.pn`并用`zM`關(guān)閉所有的折疊。文件現(xiàn)在看起來就像這樣:
~~~
factorial = (n):
+-- 5 lines: total = 1
10 times (i):
+-- 4 lines: i string print
~~~
展開第一個(gè)折疊,它看上去會(huì)是這樣:
~~~
factorial = (n):
total = 1
n to 1 (i):
+--- 2 lines: # Multiply the running total.
total.
10 times (i):
+-- 4 lines: i string print
~~~
這真不錯(cuò),但我個(gè)人喜歡依照內(nèi)容來折疊每個(gè)塊的第一行。 在本章中我們將寫下一些自定義的折疊代碼,并在最后實(shí)現(xiàn)這樣的效果:
~~~
factorial = (n):
total = 1
+--- 3 lines: n to 1 (i):
total.
+-- 5 lines: 10 times (i):
~~~
這將更為緊湊,而且(對(duì)我來說)更容易閱讀。 如果你更喜歡`indent`也不是不行,不過最好學(xué)習(xí)本章來對(duì)Vim中實(shí)現(xiàn)折疊的代碼的更深入的了解。
## 折疊原理
為了寫好自定義的折疊,我們需要了解Vim對(duì)待("thinks")折疊的方式。簡明扼要地講解下規(guī)則:
* 文件中的每行代碼都有一個(gè)"foldlevel"。它不是為零就是一個(gè)正整數(shù)。
* foldlevel為零的行_不會(huì)_被折疊。
* 有同等級(jí)的相鄰行會(huì)被折疊到一起。
* 如果一個(gè)等級(jí)X的折疊被關(guān)閉了,任何在里面的、foldlevel不小于X的行都會(huì)一起被折疊,直到有一行的等級(jí)小于X。
通過一個(gè)例子,我們可以加深理解。打開一個(gè)Vim窗口然后粘貼下面的文本進(jìn)去。
~~~
a
b
c
d
e
f
g
~~~
執(zhí)行下面的命令來設(shè)置`indent`折疊:
~~~
:setlocal foldmethod=indent
~~~
花上一分鐘玩一下折疊,觀察它是怎么工作的。
現(xiàn)在執(zhí)行下面的命令來看看第一行的foldlevel:
~~~
:echom foldlevel(1)
~~~
Vim顯示`0`?,F(xiàn)在看看第二行的:
~~~
:echom foldlevel(2)
~~~
Vim顯示`1`。試一下第三行:
~~~
:echom foldlevel(3)
~~~
Vim再次顯示`1`。這意味著第2,3行都屬于一個(gè)level1的折疊。
這是每一行的foldlevel:
~~~
a 0
b 1
c 1
d 2
e 2
f 1
g 0
~~~
重讀這一部分開頭的幾條規(guī)則。打開或關(guān)閉每個(gè)折疊,觀察foldlevel,并確保你理解了為什么會(huì)這樣折疊。
一旦你已經(jīng)自信地認(rèn)為你理解了每行的foldlevel是怎么影響折疊結(jié)構(gòu)的,繼續(xù)看下一部分。
## 首先:做一個(gè)規(guī)劃
在我們埋頭敲鍵盤之前,先為我們的折疊功能規(guī)劃出幾條大概的規(guī)則。
首先,同等縮進(jìn)的行應(yīng)該要折疊到一塊。我們也希望_上_一行也一并折疊,達(dá)到這樣的效果:
~~~
hello = (name):
'Hello, ' print
name print.
~~~
將折疊成這樣:
~~~
+-- 3 lines: hello = (name):
~~~
空行應(yīng)該算入_下_一行,因此折疊底部的空行不會(huì)包括進(jìn)去。這意味著類似這樣的內(nèi)容:
~~~
hello = (name):
'Hello, ' print
name print.
hello('Steve')
~~~
將折疊成這樣:
~~~
+-- 3 lines: hello = ():
hello('Steve')
~~~
而_不是_這樣:
~~~
+-- 4 lines: hello = ():
hello('Steve')
~~~
這當(dāng)然是屬于個(gè)人偏好的問題,但現(xiàn)在我們就這么定了。
## 開始
現(xiàn)在開始寫我們的自定義折疊代碼吧。 打開Vim,分出兩個(gè)分割,一個(gè)是`ftplugin/potion/folding.vim`,另一個(gè)是示例代碼`factorial.pn`。
在上一章我們關(guān)閉并重新打開Vim來使得`folding.vim`生效,但其實(shí)還有更簡單的方法。
不要忘記每當(dāng)設(shè)置一個(gè)緩沖區(qū)的`filetype`為`potion`的時(shí)候,在`ftplugin/potion/`下的所有文件都會(huì)被執(zhí)行。 這意味著僅需在`factorial.pn`的分割下執(zhí)行`:set ft=potion`,Vim將重新加載折疊代碼!
這比每次都關(guān)閉并重新打開文件要快多了。 唯一需要銘記的是,你得_保存_`folding.vim`到硬盤上,否則未保存的改變不會(huì)起作用。
## Expr折疊
為了獲取折疊上的無限自由,我們將使用Vim的`expr`折疊。
我們可以繼續(xù)并從`folding.vim`移除`foldignore`,因?yàn)樗辉谑褂胉indent`的時(shí)候生效。 我們也打算讓Vim使用`expr`折疊,所以把`folding.vim`改成這樣:
~~~
setlocal foldmethod=expr
setlocal foldexpr=GetPotionFold(v:lnum)
function! GetPotionFold(lnum)
return '0'
endfunction
~~~
第一行只是告訴Vim使用`expr`折疊。
第二行定義了Vim用來計(jì)算每一行的foldlevel的表達(dá)式。 當(dāng)Vim執(zhí)行某個(gè)表達(dá)式,它會(huì)設(shè)置`v:lnum`為它需要的對(duì)應(yīng)行的行號(hào)。 我們的表達(dá)式將把這個(gè)數(shù)字作為自定義函數(shù)的參數(shù)。
最后我們定義一個(gè)對(duì)任意行均返回`0`的占位(dummy)函數(shù)。 注意它返回的是一個(gè)字符串而不是一個(gè)整數(shù)。等會(huì)我們就知道為什么這么做。
繼續(xù)并重新加載折疊代碼(保存`folding.vim`并對(duì)`factorial.pn`執(zhí)行`:set ft=potion`)。 我們的函數(shù)對(duì)任意行均返回`0`,所以Vim將不會(huì)進(jìn)行任何折疊。
## 空行
讓我們先解決空行的特殊情況。修改`GetPotionFold`函數(shù)成這樣:
~~~
function! GetPotionFold(lnum)
if getline(a:lnum) =~? '\v^\s*$'
return '-1'
endif
return '0'
endfunction
~~~
我們增加了一個(gè)`if`語句來處理空行。它是怎么起效的?
首先,我們使用`getline(a:lnum)`來以字符串形式獲取當(dāng)前行的內(nèi)容。
我們把結(jié)果跟正則表達(dá)式`\v^\s*$`比較。記得`\v`表示"very magic"(我的意思是,正常的)模式。 這個(gè)正則表達(dá)式將匹配"行的開頭,任何空白字符,行的結(jié)尾"。
比較是用大小寫不敏感比較符`=~?`完成的。 技術(shù)上我們不用擔(dān)心大小寫,畢竟我們只匹配空白,但是我偏好在比較字符串時(shí)使用更清晰的方式。 如果你喜歡,可以使用`=~`代替。
如果需要喚起Vim中的正則表達(dá)式的回憶,你應(yīng)該回頭重讀"基本正則表達(dá)式"和"Grep Operator"這兩部分。
如果當(dāng)前行包括一些非空白字符,它將不會(huì)匹配,我們將如前返回`0`。
如果當(dāng)前行_匹配_正則表達(dá)式(i.e. 比如它是空的或者只有空格),就返回字符串`'-1'`。
之前我說過一行的foldlevel可以為0或者正整數(shù),所以這會(huì)發(fā)生什么?
## 特殊折疊
你自定義的表達(dá)式可以直接返回一個(gè)foldlevel,或者返回一個(gè)"特殊字符串"來告訴Vim如何折疊這一行。
`'-1'`正是其中一種特殊字符串。它告知Vim,這一行的foldlevel為"undefined"。 Vim將把它理解為"該行的foldlevel等于其上一行或下一行的較小的那個(gè)foldlevel"。
這不是我們計(jì)劃中的_最終_結(jié)果,但我們可以看到,它已經(jīng)足夠接近了,而且必將達(dá)到我們的目標(biāo)。
Vim可以把undefined的行串在一起,所以假設(shè)你有三個(gè)undefined的行和接下來的一個(gè)level1的行, 它將設(shè)置最后一行為1,接著是倒數(shù)第二行為1,然后是第一行為1。
在寫自定義的折疊代碼時(shí),你經(jīng)常會(huì)發(fā)現(xiàn)有幾種行你可以容易地設(shè)置好它們的foldlevel。 然后你就可以使用`'-1'`(或我們等會(huì)會(huì)看到的其他特殊foldlevel)來"瀑布般地"設(shè)置好剩余的行的foldlevel。
如果你重新加載了`factorial.pn`的折疊代碼,Vim_依然_不會(huì)折疊任何行。 這是因?yàn)樗械男械膄oldlevel要不是為0,就是為"undefined"。 等級(jí)為0的行將影響undefined的行,最終導(dǎo)致所有的行的foldlevel都是`0`。
## 縮進(jìn)等級(jí)輔助函數(shù)
為了處理非空行,我們需要知道它們的縮進(jìn)等級(jí),所以讓我們來創(chuàng)建一個(gè)輔助函數(shù)替我們計(jì)算它。 在`GetPotionFold`之上加上下面的函數(shù):
~~~
function! IndentLevel(lnum)
return indent(a:lnum) / &shiftwidth
endfunction
~~~
重新加載折疊代碼。在`factorial.pn`緩沖區(qū)執(zhí)行下面的命令來測試你的函數(shù):
~~~
:echom IndentLevel(1)
~~~
Vim顯示`0`,因?yàn)榈谝恍袥]有縮進(jìn)?,F(xiàn)在在第二行試試看:
~~~
:echom IndentLevel(2)
~~~
這次Vim顯示`1`。第二行開頭有四個(gè)空格,而`shiftwidth`設(shè)置為4,所以4除以4得1。
我們用它除以緩沖區(qū)的`shiftwidth`來得到縮進(jìn)等級(jí)。
為什么我們使用`&shiftwidth`而不是直接除以4? 如果有人偏好使用2個(gè)空格縮進(jìn)他們的Potion代碼,除以4將導(dǎo)致不正確的結(jié)果。 使用`shiftwidth`可以允許任何縮進(jìn)的空格數(shù)。
## 再來一個(gè)輔助函數(shù)
下一步的方向尚未明朗。讓我們停下來想想為了確定折疊非空行,還需要什么信息。
我們需要知道每一行的縮進(jìn)等級(jí)。我們已經(jīng)通過`IndentLevel`函數(shù)得到了,所以這個(gè)條件已經(jīng)滿足了。
我們也需要知道_下一個(gè)非空行_的縮進(jìn)等級(jí),因?yàn)槲覀兿M郫B段頭行到對(duì)應(yīng)的縮進(jìn)段中去。
讓我們寫一個(gè)輔助函數(shù)來得到給定行的下一個(gè)非空行的foldlevel。在`IndentLevel`上面加入下面的函數(shù):
~~~
function! NextNonBlankLine(lnum)
let numlines = line('$')
let current = a:lnum + 1
while current <= numlines
if getline(current) =~? '\v\S'
return current
endif
let current += 1
endwhile
return -2
endfunction
~~~
這個(gè)函數(shù)有點(diǎn)長,不過很簡單。讓我們逐個(gè)部分分析它。
首先我們用`line('$')`得到文件的總行數(shù)。查查文檔來了解`line()`。
接著我們設(shè)變量`current`為下一行的行號(hào)。
然后我們開始一個(gè)會(huì)遍歷文件中每一行的循環(huán)。
如果某一行匹配正則表達(dá)式`\v\S`,表示匹配"有一個(gè)_非_空白字符",它就是非空行,所以返回它的行號(hào)。
如果某一行不匹配,我們就循環(huán)到下一行。
如果循環(huán)到達(dá)文件尾行而沒有任何返回,這就說明當(dāng)前行之后_沒有_非空行! 我們返回`-2`來指明這種情況。`-2`不是一個(gè)有效的行號(hào),所以用來簡單地表示"抱歉,沒有有效的結(jié)果"。
我們可以返回`-1`,因?yàn)樗彩且粋€(gè)無效的行號(hào)。 我甚至可以選擇`0`,因?yàn)閂im中的行號(hào)從`1`開始! 所以為何我選擇`-2`這個(gè)看上去奇怪的選項(xiàng)?
我選擇`-2`是因?yàn)槲覀冋幚碇郫B代碼,而`'-1'`(和`'0'`)是特殊的Vim foldlevel字符串。
當(dāng)眼睛正掃過代碼時(shí),看到`-1`,腦子里會(huì)立刻浮現(xiàn)起"undefined foldlevel"。 這對(duì)于`0`也差不多。 我在這里選擇`-2`,就是為了突出它_不是_foldlevel,而是表示一個(gè)"錯(cuò)誤"。
如果你覺得這不可理喻,你可以安心地替換`-2`為`-1`或`0`。 這只是代碼風(fēng)格問題。
## 完成折疊函數(shù)
本章已經(jīng)顯得比較冗長了,所以現(xiàn)在把折疊函數(shù)包裝起來(wrap up)吧。把`GetPotionFold`修改成這樣:
~~~
function! GetPotionFold(lnum)
if getline(a:lnum) =~? '\v^\s*$'
return '-1'
endif
let this_indent = IndentLevel(a:lnum)
let next_indent = IndentLevel(NextNonBlankLine(a:lnum))
if next_indent == this_indent
return this_indent
elseif next_indent < this_indent
return this_indent
elseif next_indent > this_indent
return '>' . next_indent
endif
endfunction
~~~
這里的新代碼真多!讓我們分開一步步來看。
### 空行
首先我們檢查空行。這里沒有改動(dòng)。
如果不是空行,我們就準(zhǔn)備好處理非空行的情況了。
### 獲取縮進(jìn)等級(jí)
接下來我們使用兩個(gè)輔助函數(shù)來獲取當(dāng)前行和下一個(gè)非空行的折疊等級(jí)。
你可能會(huì)疑惑萬一`NextNonBlankLine`返回錯(cuò)誤碼`-2`該怎么辦。 如果這發(fā)生了,`indent(-2)`還會(huì)繼續(xù)工作。對(duì)一個(gè)不存在的行號(hào)執(zhí)行`indent()`將返回`-1`。 你可以試試`:echom indent(-2)`看看。
`-1`除以任意大于1的`shiftwidth`將返回`0`。 這好像有問題,不過它實(shí)際上不會(huì)有。現(xiàn)在暫時(shí)不用糾結(jié)于此。
### 同級(jí)縮進(jìn)
既然我們已經(jīng)得到了當(dāng)前行和下一非空行的縮進(jìn)等級(jí),我們可以比較它們并決定如何折疊當(dāng)前行。
這里又是一個(gè)`if`語句:
~~~
if next_indent == this_indent
return this_indent
elseif next_indent < this_indent
return this_indent
elseif next_indent > this_indent
return '>' . next_indent
endif
~~~
首先我們檢查這兩行是否有同樣的縮進(jìn)等級(jí)。如果相等,我們就直接把縮進(jìn)等級(jí)當(dāng)作foldlevel返回!
舉個(gè)例子:
~~~
a
b
c
d
e
~~~
假設(shè)我們正處理包含`c`的那一行,它的縮進(jìn)等級(jí)為1。 下一個(gè)非空行("d")的縮進(jìn)等級(jí)也是一樣的,所以返回`1`作為foldlevel。
假設(shè)我們正處理"a",它的縮進(jìn)等級(jí)為0。這跟下一非空行("b")的等級(jí)是一樣的,所以返回`0`作為foldlevel。
在這個(gè)簡單的示例中,可以分出兩個(gè)foldlevel。
~~~
a 0
b ?
c 1
d ?
e ?
~~~
純粹出于運(yùn)氣,這種情況也處理了在最后一行對(duì)特殊的"error"情況。 記得我們說過,如果我們的輔助函數(shù)返回`-2`,`next_indent`將會(huì)是`0`。
在這個(gè)例子中,行"e"的縮進(jìn)等級(jí)為`0`,而`next_indent`也被設(shè)為`0`,所以匹配這種情況并返回`0`。 現(xiàn)在foldlevels是這樣:
~~~
a 0
b ?
c 1
d ?
e 0
~~~
### 更低的縮進(jìn)等級(jí)
我們再來看看那個(gè)`if`語句:
~~~
if next_indent == this_indent
return this_indent
elseif next_indent < this_indent
return this_indent
elseif next_indent > this_indent
return '>' . next_indent
endif
~~~
`if`的第二部分檢查下一行的縮進(jìn)等級(jí)是否比當(dāng)前行_小_。就像是例子中行"d"的情況。
如果符合,將再一次返回當(dāng)前行的縮進(jìn)等級(jí)。
現(xiàn)在我們的例子看起來像這樣:
~~~
a 0
b ?
c 1
d 1
e 0
~~~
當(dāng)然,你可以用`||`把兩種情況連接起來,但是我偏好分開來寫以顯得更清晰。 你的想法可能不同。這只是風(fēng)格問題。
又一次,純粹出于運(yùn)氣,這種情況處理了其他來自輔助函數(shù)的"error"狀態(tài)。設(shè)想我們有一個(gè)文件像這樣:
~~~
a
b
c
~~~
第一種情況處理行"b":
~~~
a ?
b 1
c ?
~~~
行"c"為最后一行,有著縮進(jìn)等級(jí)1。由于我們的輔助函數(shù),`next_indent`將設(shè)為`0`。 這匹配`if`語句的第二部分,所以foldlevel設(shè)為當(dāng)前縮進(jìn)等級(jí),也即是`1`。
~~~
a ?
b 1
c 1
~~~
結(jié)果如我們所愿,"b"和"c"折疊到一塊去了。
### 更高的縮進(jìn)等級(jí)
現(xiàn)在還剩下最后一個(gè)`if`語句:
~~~
if next_indent == this_indent
return this_indent
elseif next_indent < this_indent
return this_indent
elseif next_indent > this_indent
return '>' . next_indent
endif
~~~
而我們的例子現(xiàn)在是:
~~~
a 0
b ?
c 1
d 1
e 0
~~~
只剩下行"b"我們還不知道它的foldlevel,因?yàn)椋?
* "b"的縮進(jìn)等級(jí)為`0`。
* "c"的縮進(jìn)等級(jí)為`1`。
* 1既不等于0,又不小于0。
最后一種情況檢查下一行的縮進(jìn)等級(jí)是否_大于_當(dāng)前行。
這種情況下Vim的`indent`折疊并不理想,也是為什么我們一開始打算寫自定義的折疊代碼的原因!
最后的情況表示,當(dāng)下一行的縮進(jìn)比當(dāng)前行多,它將返回一個(gè)以`>`開頭和_下一行_的縮進(jìn)等級(jí)構(gòu)成的字符串。 這是什么意思呢?
從折疊表達(dá)式中返回的,類似`>1`的字符串表示Vim的特殊foldlevel中的一種。 它告訴Vim當(dāng)前行需要_展開_一個(gè)給定level的折疊。
在這個(gè)簡單的例子中,我們可以簡單返回表示縮進(jìn)等級(jí)的數(shù)字,但我們很快將看到為什么要這么做。
這種情況下"b"將展開level1的折疊,使我們的例子變成這樣:
~~~
a 0
b >1
c 1
d 1
e 0
~~~
這就是我們想要的!萬歲!
## 復(fù)習(xí)
如果你一步步做到了這里,你應(yīng)該為自己感到驕傲。即使像這樣的簡單折疊代碼,也會(huì)是令人絞盡腦汁的。
在我們結(jié)束之前,讓我們重溫最初的`factorial.pn`代碼,看看我們的折疊表達(dá)式是怎么處理每一行的foldlevel的。
重新把`factorial.pn`代碼列在這里:
~~~
factorial = (n):
total = 1
n to 1 (i):
# Multiply the running total.
total *= i.
total.
10 times (i):
i string print
'! is: ' print
factorial (i) string print
"\n" print.
~~~
首先,所有的空行的foldlevel都將設(shè)為undefined:
~~~
factorial = (n):
total = 1
n to 1 (i):
# Multiply the running total.
total *= i.
total.
undefined
10 times (i):
i string print
'! is: ' print
factorial (i) string print
"\n" print.
~~~
所有折疊等級(jí)跟下一行的_相等_的行,它們的foldlevel等于折疊等級(jí):
~~~
factorial = (n):
total = 1 1
n to 1 (i):
# Multiply the running total. 2
total *= i.
total.
undefined
10 times (i):
i string print 1
'! is: ' print 1
factorial (i) string print 1
"\n" print.
~~~
在下一行的縮進(jìn)比當(dāng)前行_更少_的情況下,也是同樣的處理:
~~~
factorial = (n):
total = 1 1
n to 1 (i):
# Multiply the running total. 2
total *= i. 2
total. 1
undefined
10 times (i):
i string print 1
'! is: ' print 1
factorial (i) string print 1
"\n" print. 1
~~~
最后的情況是下一行的縮進(jìn)比當(dāng)前行更多。如果這樣,那就設(shè)當(dāng)前行的折疊等級(jí)為展開下一行的折疊:
~~~
factorial = (n): >1
total = 1 1
n to 1 (i): >2
# Multiply the running total. 2
total *= i. 2
total. 1
undefined
10 times (i): >1
i string print 1
'! is: ' print 1
factorial (i) string print 1
"\n" print. 1
~~~
現(xiàn)在我們已經(jīng)得到了文件中每一行的foldlevel。剩下的就是由Vim來解決未定義(undefined)的行。
不久前我說過undefined的行將選擇相鄰行中較小的那個(gè)foldlevel。
Vim手冊是這么講的,但不是十分地確切。 如果真是這樣的,我們的文件中的空行的foldlevel為1,因?yàn)樗噜弮尚械膄oldlevel都為1。
事實(shí)上,空行的foldlevel將被設(shè)定成0!
這就是為什么我們不直接設(shè)置`10 times(i):`的foldlevel為1。我們告訴Vim該行_展開_一個(gè)level1的折疊。 Vim能夠意識(shí)到這意味著undefined的行應(yīng)該設(shè)置成`0`而不是`1`。
這樣做背后的理由也許深埋在Vim的源碼里。 通常Vim在處理undefined行時(shí),對(duì)待特殊的foldlevel的行為都是很聰明的,所以你總能如愿以償。
一旦Vim處理完undefined行,它會(huì)得到一個(gè)對(duì)每一行的折疊情況的完整描述,看上去像這樣:
~~~
factorial = (n): 1
total = 1 1
n to 1 (i): 2
# Multiply the running total. 2
total *= i. 2
total. 1
0
10 times (i): 1
i string print 1
'! is: ' print 1
factorial (i) string print 1
"\n" print. 1
~~~
這就是了,我們完成啦!重新加載折疊代碼,在`factorial.pn`中玩玩我們神奇的折疊功能吧!
## 練習(xí)
閱讀`:help foldexpr`.
閱讀`:help fold-expr`。注意你的表達(dá)式可以返回的所有特殊字符串。
閱讀`:help getline`。
閱讀`:help indent()`。
閱讀`:help line()`。
想想為什么我們用`.`連接`>`和我們折疊函數(shù)給出的數(shù)字。如果我們使用的是`+`會(huì)怎樣?
我們在全局空間中定義了輔助函數(shù),但這不是好的做法。把它改到腳本本地的命名空間中。
放下本書,出去玩一下,讓你的大腦從本章中清醒清醒。
- 前言
- 鳴謝
- 預(yù)備知識(shí)
- 打印信息
- 設(shè)置選項(xiàng)
- 基本映射
- 模式映射
- 精確映射
- Leaders
- 編輯你的Vimrc文件
- Abbreviations
- 更多的Mappings
- 鍛煉你的手指
- 本地緩沖區(qū)的選項(xiàng)設(shè)置和映射
- 自動(dòng)命令
- 本地緩沖區(qū)縮寫
- 自動(dòng)命令組
- Operator-Pending映射
- 更多Operator-Pending映射
- 狀態(tài)條
- 負(fù)責(zé)任的編碼
- 變量
- 變量作用域
- 條件語句
- 比較
- 函數(shù)
- 函數(shù)參數(shù)
- 數(shù)字
- 字符串
- 字符串函數(shù)
- Execute命令
- Normal命令
- 執(zhí)行normal!
- 基本的正則表達(dá)式
- 實(shí)例研究:Grep 運(yùn)算符(Operator),第一部分
- 實(shí)例研究:Grep運(yùn)算符(Operator),第二部分
- 實(shí)例研究:Grep運(yùn)算符(Operator),第三部分
- 列表
- 循環(huán)
- 字典
- 切換
- 函數(shù)式編程
- 路徑
- 創(chuàng)建一個(gè)完整的插件
- 舊社會(huì)下的插件配置方式
- 新希望:用Pathogen配置插件
- 檢測文件類型
- 基本語法高亮
- 高級(jí)語法高亮
- 更高級(jí)的語法高亮
- 基本折疊
- 高級(jí)折疊
- 段移動(dòng)原理
- Potion段移動(dòng)
- 外部命令
- 自動(dòng)加載
- 文檔
- 發(fā)布
- 還剩下什么?
