作為編輯器之神,Vim 怎么可能沒有代碼折疊功能呢?但是 Vim 的上手難度極高,想要有順手的折疊功能可不是一件易事。
目前版本參考官方文檔,后面會逐漸加上自己的探索。
Vim 折疊方式
Vim 有 6 種折疊方式:
- manual //手工定義折疊
- indent //用縮進(jìn)表示折疊
- expr //用表達(dá)式來定義折疊
- syntax //用語法高亮來定義折疊
- diff //對沒有更改的文本進(jìn)行折疊
- marker //用標(biāo)志折疊
手動折疊
通過手動告訴 Vim 哪些代碼塊需要折疊來實(shí)現(xiàn)功能。
在 vimrc 中添加如下配置:
set foldmethod = manual
試一試: 把光標(biāo)置于某一段落內(nèi),并鍵入:
zfap
你將會看到該段落被一行高亮的文本所代替。你已經(jīng)創(chuàng)建一個(gè)折疊了。 zf 是個(gè)操作
符,而 ap 是一個(gè)文本對象。你可以將 zf 操作符跟任何一個(gè)移動命令聯(lián)用,為所經(jīng)之處的文本創(chuàng)建一個(gè)折疊。 zf 也能在可視模式下使用。
若要再閱讀那些文本,可以鍵入以下命令以打開該折疊:
zo
你還可以用以下命令再關(guān)閉該折疊:
zc
所有的折疊命令都以 z 開頭。展開你的想像力,這個(gè)字母看起來就像一張折疊起來的
紙的側(cè)面。而 "z" 后面可用的字母,由于采用了幫助記憶方法選擇,很容易記得住:
zf F-old creation (創(chuàng)建折疊)
zo O-pen a fold (打開折疊)
zc C-lose a fold (關(guān)閉折疊)
折疊可以嵌套: 一個(gè)含有折疊的文本區(qū)可以被再次折疊。例如,你可以折疊本節(jié)內(nèi)每一段
落,然后折疊本章內(nèi)所有的節(jié)。試試看。你將注意到,打開全章的折疊,會將節(jié)的折疊還
原得跟以前一樣,有些打開,而有些關(guān)閉。
假定你已經(jīng)創(chuàng)建了若干折疊,而現(xiàn)在需要閱覽全部文本。你可以移到每個(gè)折疊處,并鍵入
"zo"。若要做得更快,可以用這個(gè)命令:
zr
這將減少 (R-educe) 折疊。相反的操作是:
zm
這將折疊更多 (M-ore)。你可以重復(fù) "zr" 和 "zm" 來打開和關(guān)閉若干層嵌套的折疊。
如果你有一個(gè)嵌套了好幾層深的折疊,你可以用這個(gè)命令把它們?nèi)看蜷_:
zR
這將減少折疊直至一個(gè)也不剩。而用下面這個(gè)命令你可以關(guān)閉所有的折疊:
zM
這將增加折疊,直至所有的折疊都關(guān)閉了。
縮進(jìn)折疊
Vim 通過文本的縮進(jìn)來自動添加折疊,適用于 Python 和大綱。
在 vimrc 中添加如下配置:
set foldmethod = indent
然后你可以用 zm 和 zr 命令增加和減少折疊。在下面這個(gè)例文上很容易看明白:
本行沒有縮進(jìn)
本行被縮進(jìn)一次
本行被縮進(jìn)兩次
本行被縮進(jìn)兩次
本行被縮進(jìn)一次
本行沒有縮進(jìn)
本行被縮進(jìn)一次
本行被縮進(jìn)一次
注意 縮進(jìn)多少和折疊深度之間的關(guān)系倚賴于 shiftwidth 選項(xiàng)。每個(gè) shiftwidth
選項(xiàng)規(guī)定的縮進(jìn)寬度,在折疊深度上加一。這被稱為一個(gè)折疊級別。
當(dāng)你使用 zr 和 zm 命令時(shí),你實(shí)際上是在增加或減少 foldlevel 選項(xiàng)。你也可以直接設(shè)置它:
:set foldlevel=3
這意味著,所有縮進(jìn)等于或大于 shiftwidth 三倍的折疊將被關(guān)閉。折疊級別設(shè)定得越
低,越多的折疊將被關(guān)閉。當(dāng) foldlevel 為零時(shí),所有的折疊都將被關(guān)閉。 zM 把
foldlevel 設(shè)為零。相反的命令 zR 把 foldlevel 設(shè)為文件中最深的折疊級別。
因此,有兩種方法開啟和關(guān)閉折疊:
設(shè)定折疊級別。
這提供了一種極快的 "縮小" 方法來查看文本結(jié)構(gòu),移動光標(biāo),以及重新 "放大" 到具體的文本。利用
zo和zc命令打開和關(guān)閉指定的折疊。
這個(gè)方法允許你僅僅打開那些你要打開的折疊,而不影響其它的折疊。
這兩種方法可以結(jié)合起來用: 你可以先用幾次 zm 以關(guān)閉大多數(shù)折疊,然后用 zo
打開一個(gè)指定的折疊?;蛘撸? zR 打開所有的折疊,然后用 zc 關(guān)閉指定的折疊。
但是,當(dāng)折疊方法 foldmethod 的值為 indent 時(shí),你不能手動定義折疊。因?yàn)槟菢?br>
會引起縮進(jìn)寬度和折疊級別之間的沖突。
標(biāo)志折疊
Vim 通過事先添加的標(biāo)志折疊代碼塊。
在 vimrc 中添加如下配置:
set foldmethod = marker
以下列 C 程序片段為例:
/* foobar () {{{ */
int foobar()
{
/* return a value {{{ */
return 42;
/* }}} */
}
/* }}} */
請注意,折疊行將顯示位于標(biāo)志之前的文字。這正好用來說明該折疊包含了什么。
令人十分困擾的是,當(dāng)某些文本行移動后,標(biāo)志不再正確地配對。這種局面可以利用編號
標(biāo)志來避免。例如:
/* global variables {{{1 */
int varA,varB;
/* functions {{{1 */
/* funcA() {{{2 */
void funcA() {}
/* funcB() {{{2 */
void funcB() {}
/* }}}1 */
每一個(gè)編號標(biāo)志表示一個(gè)編號指定級別的折疊的開始。這將使任何較高層次的折疊在此結(jié)
束。你可以只用編號標(biāo)志的開始符定義所有的折疊。只有當(dāng)你要明確地在另一個(gè)開始前結(jié)
束一個(gè)折疊時(shí),你才需要加一個(gè)標(biāo)志停止符。
語法折疊
Vim 為每一種不同的語言使用一個(gè)不同的語法文件。語法文件為文件中各種不同語法項(xiàng)定義顏色。在語法文件中,你可以加入一些帶有 "fold" 參數(shù)的語法項(xiàng)。這些語法項(xiàng)將定義折疊。
在 vimrc 中添加如下配置:
set foldmethod = syntax
zc 關(guān)閉折疊
zo 打開折疊
za 打開/關(guān)閉折疊互相切換
關(guān)閉 Vim 默認(rèn)折疊
當(dāng)我們選好自動折疊后,打開代碼是就會發(fā)現(xiàn) vim 默認(rèn)把所有代碼都折疊了,如果不想要這個(gè)選項(xiàng),可以在 vimrc 添加如下配置關(guān)閉默認(rèn)折疊:
set foldlevelstart=99
折疊插件
vim 默認(rèn)的折疊配置并不容易上手,對于 C++ 項(xiàng)目來說,vim 自帶的語法折疊太過簡單,很多地方都不能折疊,而我目前又不想去修改 cpp.vim 語法文件,經(jīng)過大量搜索,終于找了一個(gè)增強(qiáng)版的折疊插件。
插件地址:GitHub 主頁
安裝
在 .vimrc 合適位置添加如下代碼(Vundle 安裝):
Plugin 'LucHermitte/VimFold4C'
輸入
:PluginInstall
等待安裝完成。
使用
跟默認(rèn)的一致,如果想要進(jìn)階,可以去項(xiàng)目主頁看看。