作为编辑器之神,Vim 怎么可能没有代码折叠功能呢?但是 Vim 的上手难度极高,想要有顺手的折叠功能可不是一件易事。
目前版本参考官方文档,后面会逐渐加上自己的探索。
Vim 折叠方式
Vim 有 6 种折叠方式:
- manual //手工定义折叠
- indent //用缩进表示折叠
- expr //用表达式来定义折叠
- syntax //用语法高亮来定义折叠
- diff //对没有更改的文本进行折叠
- marker //用标志折叠
手动折叠
通过手动告诉 Vim 哪些代码块需要折叠来实现功能。
在 vimrc
中添加如下配置:
set foldmethod = manual
试一试: 把光标置于某一段落内,并键入:
zfap
你将会看到该段落被一行高亮的文本所代替。你已经创建一个折叠了。 zf
是个操作
符,而 ap
是一个文本对象。你可以将 zf
操作符跟任何一个移动命令联用,为所经之处的文本创建一个折叠。 zf
也能在可视模式下使用。
若要再阅读那些文本,可以键入以下命令以打开该折叠:
zo
你还可以用以下命令再关闭该折叠:
zc
所有的折叠命令都以 z
开头。展开你的想像力,这个字母看起来就像一张折叠起来的
纸的侧面。而 "z" 后面可用的字母,由于采用了帮助记忆方法选择,很容易记得住:
zf F-old creation (创建折叠)
zo O-pen a fold (打开折叠)
zc C-lose a fold (关闭折叠)
折叠可以嵌套: 一个含有折叠的文本区可以被再次折叠。例如,你可以折叠本节内每一段
落,然后折叠本章内所有的节。试试看。你将注意到,打开全章的折叠,会将节的折叠还
原得跟以前一样,有些打开,而有些关闭。
假定你已经创建了若干折叠,而现在需要阅览全部文本。你可以移到每个折叠处,并键入
"zo"。若要做得更快,可以用这个命令:
zr
这将减少 (R-educe) 折叠。相反的操作是:
zm
这将折叠更多 (M-ore)。你可以重复 "zr" 和 "zm" 来打开和关闭若干层嵌套的折叠。
如果你有一个嵌套了好几层深的折叠,你可以用这个命令把它们全部打开:
zR
这将减少折叠直至一个也不剩。而用下面这个命令你可以关闭所有的折叠:
zM
这将增加折叠,直至所有的折叠都关闭了。
缩进折叠
Vim 通过文本的缩进来自动添加折叠,适用于 Python 和大纲。
在 vimrc
中添加如下配置:
set foldmethod = indent
然后你可以用 zm 和 zr 命令增加和减少折叠。在下面这个例文上很容易看明白:
本行没有缩进
本行被缩进一次
本行被缩进两次
本行被缩进两次
本行被缩进一次
本行没有缩进
本行被缩进一次
本行被缩进一次
注意 缩进多少和折叠深度之间的关系倚赖于 shiftwidth
选项。每个 shiftwidth
选项规定的缩进宽度,在折叠深度上加一。这被称为一个折叠级别。
当你使用 zr
和 zm
命令时,你实际上是在增加或减少 foldlevel
选项。你也可以直接设置它:
:set foldlevel=3
这意味着,所有缩进等于或大于 shiftwidth
三倍的折叠将被关闭。折叠级别设定得越
低,越多的折叠将被关闭。当 foldlevel
为零时,所有的折叠都将被关闭。 zM
把
foldlevel
设为零。相反的命令 zR
把 foldlevel
设为文件中最深的折叠级别。
因此,有两种方法开启和关闭折叠:
设定折叠级别。
这提供了一种极快的 "缩小" 方法来查看文本结构,移动光标,以及重新 "放大" 到具体的文本。利用
zo
和zc
命令打开和关闭指定的折叠。
这个方法允许你仅仅打开那些你要打开的折叠,而不影响其它的折叠。
这两种方法可以结合起来用: 你可以先用几次 zm
以关闭大多数折叠,然后用 zo
打开一个指定的折叠。或者,用 zR
打开所有的折叠,然后用 zc
关闭指定的折叠。
但是,当折叠方法 foldmethod
的值为 indent
时,你不能手动定义折叠。因为那样
会引起缩进宽度和折叠级别之间的冲突。
标志折叠
Vim 通过事先添加的标志折叠代码块。
在 vimrc
中添加如下配置:
set foldmethod = marker
以下列 C 程序片段为例:
/* foobar () {{{ */
int foobar()
{
/* return a value {{{ */
return 42;
/* }}} */
}
/* }}} */
请注意,折叠行将显示位于标志之前的文字。这正好用来说明该折叠包含了什么。
令人十分困扰的是,当某些文本行移动后,标志不再正确地配对。这种局面可以利用编号
标志来避免。例如:
/* global variables {{{1 */
int varA,varB;
/* functions {{{1 */
/* funcA() {{{2 */
void funcA() {}
/* funcB() {{{2 */
void funcB() {}
/* }}}1 */
每一个编号标志表示一个编号指定级别的折叠的开始。这将使任何较高层次的折叠在此结
束。你可以只用编号标志的开始符定义所有的折叠。只有当你要明确地在另一个开始前结
束一个折叠时,你才需要加一个标志停止符。
语法折叠
Vim 为每一种不同的语言使用一个不同的语法文件。语法文件为文件中各种不同语法项定义颜色。在语法文件中,你可以加入一些带有 "fold" 参数的语法项。这些语法项将定义折叠。
在 vimrc
中添加如下配置:
set foldmethod = syntax
zc
关闭折叠
zo
打开折叠
za
打开/关闭折叠互相切换
关闭 Vim 默认折叠
当我们选好自动折叠后,打开代码是就会发现 vim 默认把所有代码都折叠了,如果不想要这个选项,可以在 vimrc
添加如下配置关闭默认折叠:
set foldlevelstart=99
折叠插件
vim 默认的折叠配置并不容易上手,对于 C++ 项目来说,vim 自带的语法折叠太过简单,很多地方都不能折叠,而我目前又不想去修改 cpp.vim
语法文件,经过大量搜索,终于找了一个增强版的折叠插件。
插件地址:GitHub 主页
安装
在 .vimrc 合适位置添加如下代码(Vundle 安装):
Plugin 'LucHermitte/VimFold4C'
输入
:PluginInstall
等待安装完成。
使用
跟默认的一致,如果想要进阶,可以去项目主页看看。