2011-06-03 58 views
2

我目前正在爲Vim開發一個插件來管理清單。Vim腳本編制:匹配表達式並計算折線

我目前在語法文件中使用「:setlocal foldmethod = indent」來處理每個清單文檔中的所有摺疊。但是,我想創建一個更靈活的摺疊功能,並且不會依賴線條的縮進來確定它是否摺疊。

下面是一個例子清單:

+ Parent 
    * Child 
    * Child 
    * Child 

當用戶按壓了「+父」線<leader> VV,它把它摺疊下方的線,因爲它們縮進一個級別。這樣做的問題在於,foldmethod可以在其他緩衝區和摺疊線附近進行摺疊,而不需要摺疊。

這裏是我怎麼想的處理它至今:

function! FoldLines() 
    let l:line = getline(line(".") + 1) 

    " If next line is a child 
    if match(l:line, '^\s*\*') >= 0 

    " Loop until blank line is found, and store line numbers in a list 
    endif 

    " Select lines from list and fold 
endfunction 

我不知道如何處理循環和摺疊。有什麼建議麼?

UPDATE

好,karategeek6的解決方案可在一定程度上,但我沒有提到我的插件也切換清單項。

例子:

+ Parent 
    × Child - Toggled 
    * Child - Standard 

我可能是錯的,但我不認爲foldexpr將能夠處理與兩行*和開頭×。

我已經試過:

set foldexpr=strlen(substitute(substitute(getline(v:lnum),'\\s','',\"g\"),'[^[*|×]].*','','')) 

,但似乎並沒有工作,要麼。

+0

如果你已經把'[^ [* |×]]',嘗試'[^ * x]'。 – Johnsyweb 2011-06-04 06:42:54

+0

@Johnsyweb, 謝謝。這個工作更好一些,但由於某種原因,它不喜歡當我的+ Parent行被關閉後的第一行。不過,如果第一個孩子沒有看到它,它會摺疊。 – 2011-06-04 07:00:43

回答

1

好吧,似乎我找到了解決方案。我結束了使用這個:

setlocal foldlevel=0 
setlocal foldmethod=expr 
setlocal foldexpr=FoldLevel(v:lnum) 

function! FoldLevel(linenum) 
    let linetext = getline(a:linenum) 
    let level = indent(a:linenum)/4 
    if linetext =~ '^\s*[\*|×]' 
    let level = 20 
    endif 
    return level 
endfunction 
2

這聽起來像你希望它通過表達式摺疊。根據user manual,按表達式摺疊,可以使用表達式來設置每一行的摺疊級別。用戶手冊給出了一個我認爲可以適應您的需求的例子。

:set foldmethod=expr 
:set foldexpr=strlen(substitute(substitute(getline(v:lnum),'\\s','',\"g\"),'[^*].*','','')) 

可以在用戶手冊讀更多的例子,但概括地說,它將設置摺疊級別等於領導「*」的數量,而不管空白的。

希望這不是你正在尋找的東西,或者可以指向正確的方向。在按表達式摺疊時要記住的關鍵方面是您決定每行的摺疊級別,而不是摺疊哪些行。

+0

謝謝!這只是完美的,但我也會檢查一下手冊,看看那會是什麼。 – 2011-06-04 06:15:18