摺疊
Nvim :help
頁面,從 原始碼 使用 tree-sitter-vimdoc 解析器產生。
當將
'foldmethod' 設定為 "manual" 以外的值時,所有摺疊都會被刪除並建立新的摺疊。切換到 "manual" 方法並不會刪除現有的摺疊。這可以用來先自動定義摺疊,然後手動變更它們。
有六種方法可以選取摺疊:manual 手動定義摺疊 indent 縮排越多表示摺疊層級越高 expr 指定一個表達式來定義摺疊 syntax 透過語法高亮定義摺疊 diff 未變更文字的摺疊 marker 透過文字中的標記定義摺疊
使用命令手動定義摺疊區域。這也可以被腳本使用,解析文字來尋找摺疊。
摺疊的層級僅由其巢狀結構定義。要增加一行範圍的摺疊層級,請在其中定義具有相同行的摺疊。
摺疊會根據行的縮排自動定義。
摺疊層級是根據行的縮排除以
'shiftwidth'(向下取整)計算得出的。一系列具有相同或更高摺疊層級的行構成一個摺疊,具有更高層級的行形成一個巢狀摺疊。
某些行會被忽略,並取得上方或下方行的摺疊層級,取兩者中較低者。這些是空白行或空格行,以及以
'foldignore' 中的字元開頭的行。在檢查
'foldignore' 中的字元之前,會跳過空白字元。對於 C 語言,使用 "#" 來忽略預處理器行。
摺疊會根據其摺疊層級自動定義,就像 "indent" 方法一樣。評估
'foldexpr' 選項的值以取得行的摺疊層級。範例:這將為所有以 tab 開頭的連續行建立一個摺疊
:set foldexpr=getline(v:lnum)[0]==\"\\t\"
這會將段落分隔為空白行
:set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
這會做同樣的事情
:set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1
請注意,必須使用反斜線來跳脫 ":set" 處理方式不同的字元(空格、反斜線、雙引號等,請參閱
option-backslash)。
以下是評估表達式的條件
目前緩衝區和視窗是為該行設定的。
變數 "v:lnum" 設定為行號。
結果用於摺疊層級的方式如下:值 意義 ~ 0 該行不在摺疊中 1, 2, .. 該行在具有此層級的摺疊中 -1 摺疊層級未定義,使用此行之前或之後的行的摺疊層級,取兩者中較低者。 "=" 使用上一行的摺疊層級 "a1", "a2", .. 將上一行的摺疊層級加一、加二,.. ,使用結果作為目前行的摺疊層級 "s1", "s2", .. 從上一行的摺疊層級減一、減二,.. ,使用結果作為下一行的摺疊層級 "<1", "<2", .. 具有此層級的摺疊在此行結束 ">1", ">2", .. 具有此層級的摺疊在此行開始
不需要使用 ">1" ("<1") 標記摺疊的開始(結束),當摺疊層級高於(低於)上一行的摺疊層級時,摺疊也會開始(結束)。
表達式不得有副作用。緩衝區中的文字、游標位置、搜尋模式、選項等不得變更。如果小心,您可以變更並還原它們。
如果表達式中存在一些錯誤,或者結果值無法辨識,則不會出現錯誤訊息,並且摺疊層級將為零。為了進行偵錯,可以將
'debug' 選項設定為 "msg",屆時錯誤訊息將可見。
注意:由於必須為每一行評估表達式,因此此摺疊方法可能會非常慢!
盡量避免使用 "="、"a" 和 "s" 回傳值,因為 Vim 通常必須向後搜尋定義摺疊層級的行。這可能會很慢。
使用 "a1" 和 "s1" 的範例:對於多行 C 註解,包含 "/*" 的行會回傳 "a1" 來開始摺疊,而包含 "*/" 的行會回傳 "s1" 以在該行之後結束摺疊
if match(thisline, '/\*') >= 0
return 'a1'
elseif match(thisline, '\*/') >= 0
return 's1'
else
return '='
endif
但是,這不適用於單行註解、字串等。
foldlevel() 可以用於計算相對於先前摺疊層級的摺疊層級。但請注意,如果層級尚未知,foldlevel() 可能會回傳 -1。而且它會回傳行首的層級,而摺疊可能會在該行結束。
摺疊可能無法正確更新。您可以使用
zx 或
zX 強制更新摺疊。
請小心指定正確的語法同步。如果沒有正確執行,摺疊可能會與顯示的高亮不同。當使用比對多行的模式時,這一點尤其相關。如果存有疑問,請嘗試使用暴力同步
:syn sync fromstart
摺疊是針對不屬於變更或接近變更的文字自動定義的。
只有在為目前的視窗設定
'diff' 選項並顯示變更時,此方法才能正常運作。否則,整個緩衝區將會是一個大型摺疊。
可以使用
'diffopt' 選項指定內容。也就是說,不包含在摺疊中的摺疊和變更之間的行數。例如,要使用 8 行的內容
:set diffopt=filler,context:8
預設內容為六行。
當同時設定
'scrollbind' 時,Vim 會嘗試在其他 diff 視窗中保持相同的摺疊開啟,以便可以看見相同的文字。
文字中的標記會告訴摺疊的開始和結束位置。這讓您可以精確地指定摺疊。這將允許刪除和放置摺疊,而不會有包含錯誤行的風險。
'foldtext' 選項通常設定為在摺疊行中顯示標記之前的文字。這使得可以為摺疊命名。
標記可以包含層級,也可以使用比對的配對。包含層級更容易,您不必新增結束標記,並且避免不匹配的標記配對問題。範例
/* global variables {{{1 */
int varA, varB;
/* functions {{{1 */
/* funcA() {{{2 */
void funcA() {}
/* funcB() {{{2 */
void funcB() {}
{{{ }}} 摺疊從 "{{{" 標記開始。以下數字指定摺疊層級。會發生什麼情況取決於目前摺疊層級與標記給定的層級之間的差異:1. 如果遇到具有相同摺疊層級的標記,則先前的摺疊結束,並且開始另一個具有相同層級的摺疊。2. 如果找到具有更高摺疊層級的標記,則會開始巢狀摺疊。3. 如果找到具有較低摺疊層級的標記,則會結束到此層級(包含此層級)的所有摺疊,並且會開始具有指定層級的摺疊。
該數字表示摺疊層級。不能使用零(會忽略層級為零的標記)。您可以使用帶有數字的 "}}}" 來表示結束的摺疊的層級。下一行的摺疊層級將比指示的層級少一。請注意,Vim 不會回頭查看匹配標記的層級(那會花費太多時間)。範例
{{{1
fold level here is 1
{{{3
fold level here is 3
}}}3
fold level here is 2
您也可以使用 "{{{" 和 "}}}" 標記的匹配配對來定義摺疊。每個 "{{{" 會將摺疊層級增加一,每個 "}}}" 會將摺疊層級減少一。請小心保持標記匹配!範例
{{{
fold level here is 1
{{{
fold level here is 2
}}}
fold level here is 1
您可以混合使用帶有數字和不帶有數字的標記。一種有用的方法是為大型摺疊使用編號標記,並在本機函數中使用未編號的標記。例如,為您檔案的章節(例如「結構定義」、「區域變數」和「函數」)使用第一層摺疊。為每個定義和函數使用第二層標記,在函數內使用未編號的標記。當您變更函數以分割摺疊時,不必重新編號標記。
可以使用
'foldmarker' 選項設定標記。建議將其保持在預設值 "{{{,}}}",以便可以在 Vim 使用者之間交換檔案。僅當檔案需要時才變更它(例如,它包含來自其他摺疊編輯器的標記,或預設標記為檔案的語言造成問題)。
fold-create-marker "zf" 可以用來建立由標記定義的摺疊。Vim 會為您插入標記。Vim 會附加開始和結束標記,如
'foldmarker' 中所指定。標記會附加到行尾。
'commentstring' 會在不為空時使用。當以下情況時,這無法正常運作
該行已經包含具有層級編號的標記。然後 Vim 不知道該怎麼做。
附近的摺疊在其標記中使用會造成干擾的層級編號。
該行位於註解內,
'commentstring' 不為空,且巢狀註解無法運作。例如,對於 C:在註解中新增
/* {{{ */
會截斷現有的註解。請將標記放在註解之前或之後,或手動新增標記。一般而言,當您已經有帶有層級編號的標記時,讓 Vim 建立標記並不是一個好主意。
所有摺疊指令都以 "z" 開頭。提示:從側面看,"z" 看起來像一張摺疊的紙。
zF zF 為 [count] 行建立摺疊。作用類似於 "zf"。
:{range}fo[ld]
:fold :fo 為
{range}
中的行建立摺疊。作用類似於 "zf"。
zd E351 zd 刪除游標處的一個摺疊。當游標位於摺疊的行上時,該摺疊將被刪除。巢狀摺疊會向上移動一層。在視覺模式下,選定區域中(部分)的所有摺疊的一層會被刪除。注意:這很容易刪除比您預期的更多摺疊,並且手動摺疊沒有復原功能。僅當
'foldmethod' 為 "manual" 或 "marker" 時才有效。另請參閱
fold-delete-marker。
zo zo 開啟游標下的一個摺疊。當給定計數時,將會開啟該深度層級的摺疊。在視覺模式下,選定區域中所有行的摺疊都會開啟一層。
zO zO 遞迴開啟游標下的所有摺疊。不包含游標行的摺疊將保持不變。在視覺模式下,它會開啟選定區域中的所有摺疊,也包括那些僅部分選定的摺疊。
zc zc 關閉游標下的一個摺疊。當給定計數時,將會關閉該深度層級的摺疊。在視覺模式下,選定區域中所有行的摺疊都會關閉一層。
'foldenable' 將會被設定。
zC zC 遞迴關閉游標下的所有摺疊。不包含游標行的摺疊將保持不變。在視覺模式下,它會關閉選定區域中的所有摺疊,也包括那些僅部分選定的摺疊。
'foldenable' 將會被設定。
za za 摘要:切換游標下的摺疊。當在關閉的摺疊上時:開啟它。當摺疊是巢狀時,您可能需要多次使用 "za"。當給定計數時,將會開啟該數量的關閉摺疊。當在開啟的摺疊上時:關閉它並設定
'foldenable'。這只會關閉一層,因為再次使用 "za" 會開啟摺疊。當給定計數時,將會關閉該數量的摺疊(這與重複多次 "za" 不同)。
zv zv 檢視游標行:開啟足夠的摺疊以使游標所在的行不被摺疊。
:foldo :foldopen :{range}foldo[pen][!] 開啟
{range}
中的摺疊。當加上 [!] 時,所有摺疊都會開啟。用於查看
{range}
中的所有文字很有用。沒有 [!] 時,會開啟一層摺疊。
:foldc :foldclose :{range}foldc[lose][!] 關閉
{range}
中的摺疊。當加上 [!] 時,所有摺疊都會關閉。用於隱藏
{range}
中的所有文字很有用。沒有 [!] 時,會關閉一層摺疊。
在摺疊之間移動
[z [z 移動到目前開啟的摺疊的開始處。如果已經在開始處,則移動到包含它的摺疊的開始處。如果沒有包含摺疊,則命令失敗。當使用計數時,會重複執行該命令 [count] 次。
]z ]z 移動到目前開啟的摺疊的結尾處。如果已經在結尾處,則移動到包含它的摺疊的結尾處。如果沒有包含摺疊,則命令失敗。當使用計數時,會重複執行該命令 [count] 次。
zj zj 向下移動到下一個摺疊的開始處。關閉的摺疊算作一個摺疊。當使用計數時,會重複執行該命令 [count] 次。此命令可以在
operator 之後使用。
zk zk 向上移動到上一個摺疊的結尾處。關閉的摺疊算作一個摺疊。當使用計數時,會重複執行該命令 [count] 次。此命令可以在
operator 之後使用。
:[range]foldd[oopen]
{cmd}
:foldd :folddo :folddoopen 對所有不在關閉摺疊中的行執行
{cmd}
。當給定 [range] 時,僅使用這些行。每次執行
{cmd}
時,游標都會定位在執行該命令的行上。這與 ":global" 命令的作用類似:首先標記所有不在關閉摺疊中的行。然後對所有標記的行執行
{cmd}
。因此,當
{cmd}
變更摺疊時,這不會影響其執行位置(當然,除非刪除了行)。範例
:folddoopen s/end/loop_end/ge
請注意使用 "e" 旗標以避免在 "end" 不匹配時出現錯誤訊息。
關閉摺疊的顏色由 Folded 群組設定
hl-Folded。摺疊欄的顏色由 FoldColumn 群組設定
hl-FoldColumn。設定顏色的範例
:highlight Folded guibg=grey guifg=blue
:highlight FoldColumn guibg=darkgrey guifg=white
'foldtext' 是一個字串選項,用於指定一個表達式。此表達式會被評估以取得關閉摺疊所顯示的文字。範例
:set foldtext=v:folddashes.substitute(getline(v:foldstart),'/\\*\\\|\\*/\\\|{{{\\d\\=','','g')
這會顯示摺疊的第一行,並移除 "/*"、"*/" 和 "{{{"。請注意使用反斜線來避免某些字元被 ":set" 命令解譯。定義一個函數並調用它會簡單得多
:set foldtext=MyFoldText()
:function MyFoldText()
: let line = getline(v:foldstart)
: let sub = substitute(line, '/\*\|\*/\|{{{\d\=', '', 'g')
: return v:folddashes .. sub
:endfunction
評估
'foldtext' 是在
sandbox 中完成的。目前的視窗會設定為顯示該行的視窗。
錯誤會被忽略。對於除錯,請將
'debug' 選項設定為 "throw"。
預設值為
foldtext()。這會為大多數類型的摺疊返回合理的文字。如果您不喜歡它,您可以指定自己的
'foldtext' 表達式。它可以使用這些特殊的 Vim 變數:v:foldstart 摺疊中第一行的行號 v:foldend 摺疊中最後一行的行號 v:folddashes 包含虛線以表示摺疊層級的字串。v:foldlevel 摺疊的摺疊層級
產生的行會被截斷以適合視窗,它永遠不會換行。當文字之後有空間時,它會使用
'fillchars' 所指定的字元填滿。
'foldcolumn' 是一個數字,設定視窗側邊欄的寬度,以指示摺疊。當它為零時,則沒有摺疊欄。一個正常的值是 auto:9。最大值為 9。
一個開啟的摺疊會以頂部有一個 '-',下方有 '|' 字元的欄位指示。此欄位會在開啟的摺疊停止處停止。當摺疊巢狀時,巢狀摺疊會在其包含的摺疊右邊一個字元的位置。
一個關閉的摺疊會以 '+' 指示。
當摺疊欄太窄而無法顯示所有巢狀摺疊時,會顯示數字以指示巢狀層級。
滑鼠也可以通過點擊摺疊欄來開啟和關閉摺疊。
點擊 '+' 以開啟此列中關閉的摺疊。
點擊任何其他非空白字元以關閉此列中開啟的摺疊。
其他選項
當向上或向下移動游標以及滾動時,游標將移動到一連串摺疊行的第一行。當游標已經在摺疊的行上時,它會移動到下一個未摺疊的行或下一個關閉的摺疊。
當游標在摺疊的行上時,游標始終顯示在第一列。尺規會顯示實際游標位置,但由於該行已摺疊,因此無法在那裡顯示。
許多移動命令會將一連串摺疊的行視為空行。例如,「w」命令會在第一列停止一次。
當在關閉的摺疊中開始搜尋時,它不會在目前的摺疊中找到匹配項。這就像向前搜尋始終從關閉的摺疊末尾開始,而向後搜尋則從關閉的摺疊開始處開始。
當處於插入模式時,游標行永遠不會被摺疊。這讓您可以看到您輸入的內容!
當使用運算子時,關閉的摺疊會作為整體包含在內。因此,「dl」會刪除游標下整個關閉的摺疊。
對於在緩衝區行上工作的 Ex 命令,範圍會調整為始終從關閉的摺疊的第一行開始,並在關閉的摺疊的最後一行結束。因此,此命令
:s/foo/bar/g
當游標位於關閉的摺疊上使用時,會將摺疊的所有行中的「foo」替換為「bar」。這不會發生在
:folddoopen 和
:folddoclosed。
當編輯先前編輯過的緩衝區時,會再次使用上次使用的摺疊設定。對於手動摺疊,會還原定義的摺疊。對於所有摺疊方法,會還原手動開啟和關閉的摺疊。如果此緩衝區已在此視窗中編輯過,則會使用當時的值。否則,會使用上次編輯該緩衝區的視窗中的值。