Vim支持基于语法的C代码折叠,效果很好。 但是,函数名称不是折叠的一部分,只是{和}之间的部分。
给出了这个示例代码:
static inline bool uFuzzyCompare(double p1, double p2)
{
return (uAbs(p1 - p2) <= 0.000000000001 * uMin(uAbs(p1), uAbs(p2)));
}
static inline bool uFuzzyComparef(float p1, float p2)
{
return (uAbsf(p1 - p2) <= 0.00001f * uMinf(uAbsf(p1), uAbsf(p2)));
}
static inline bool uFuzzyIsNull(double d)
{
return uAbs(d) <= 0.000000000001;
}
static inline bool uFuzzyIsNullf(float f)
{
return uAbs(f) <= 0.00001f;
}
这看起来像这样:
static inline bool uFuzzyCompare(double p1, double p2)
+-- 3 lines: {----------------------------------------------------------------------------------------------------------------------------------------------------------------
static inline bool uFuzzyComparef(float p1, float p2)
+-- 3 lines: {----------------------------------------------------------------------------------------------------------------------------------------------------------------
static inline bool uFuzzyIsNull(double d)
+-- 3 lines: {----------------------------------------------------------------------------------------------------------------------------------------------------------------
static inline bool uFuzzyIsNullf(float f)
+-- 3 lines: {----------------------------------------------------------------------------------------------------------------------------------------------------------------
我更喜欢这个:
+-- uFuzzyCompare(...) (5 lines)
+-- uFuzzyComparef(...) (5 lines)
+-- uFuzzyIsNull(...) (5 lines)
+-- uFuzzyIsNullf(...) (5 lines)
这意味着将函数声明包含在fold和空行中,并将函数名称显示为折叠文本。
这有可能吗? 也许使用foldmethod表达式,但我不知道在不编写完整的C语法分析器的情况下创建此表达式的好方法。 所以使用语法解析器是最好的,但我找不到任何配置选项。
的问候, 格哈德
答案 0 :(得分:3)
这将帮助您顺利前进。它目前只折叠顶级功能。把它放在~/.vim/ftplugin/c.vim
function! CFold()
if getline(v:lnum - 1)[0] ==# '}'
return '<1'
elseif getline(v:lnum + 1)[0] ==# '{'
return '>1'
endif
return '='
endfunction
function! CFoldText()
let line = getline(v:foldstart)
let sub = substitute(line, '.*\<\(\w\+\)(.*).*', '\1(...)', 'g')
return '+-- ' . sub . ' (' . (v:foldend - v:foldstart + 1) . ' lines)'
endfunction
setlocal foldmethod=expr
setlocal foldexpr=CFold()
setlocal foldtext=CFoldText()
setlocal fillchars-=fold:-
示例文本的输出
+-- uFuzzyCompare(...) (5 lines)
+-- uFuzzyComparef(...) (5 lines)
+-- uFuzzyIsNull(...) (5 lines)
+-- uFuzzyIsNullf(...) (5 lines)
这是如何运作的。当你将foldmethod设置为expr时,vim使用foldexpr中的表达式来确定它应该如何折叠。我正在做的就是检查第一列中当前后面的行是否包含{
,如果是,我们将折叠级别设置为>1
,表示开始第1级的折叠。在}
行结束。 <1
表示结束了1级的折叠。
要设置折叠文本,我们只需提取函数并用...
替换参数(对于参数为多行的行,这可能会中断)。然后我们返回一个格式很好的字符串。 v:foldstart
和v:foldend
是设置的变量,表示折叠开始和结束的哪一行。
从fillchars中删除fold:-
会删除折叠文本后的破折号。
相关帮助页面:h 'foldmethod'
,:h foldexpr
,:h foldtext
和:h 'fillchars'
答案 1 :(得分:0)
正确处理折叠并非易事。
例如,支持K&amp; R缩进样式需要一些工作。
if (a_or_b) {
if (foo) {
a1();
} else if (bar) {
a2();
} else {
a3();
}
} else {
b();
}
智能地/好地折叠像do {...} while(cond);
这样的东西使事情变得更加复杂(因为我们需要支持嵌套的上下文)
do
{
act();
do {
a2();
}
while (inner);
}
while(outer)
;
无论如何,我已经开发出一个在合理的时间内尽力而为的解决方案:VimFold4C - 但是我还不支持do { ... } while(cond);
,也没有利用在开头出现的评论折叠区:(。