我想设置两种折叠方法
:set foldmethod=indent 并保留其所有功能隐藏评论
:set foldmethod=marker
:set foldmarker=/*,*/
我发现这是不可能的.是否有可能实现所需的折叠并将其设置.vimrc或使用某些脚本或插件?
在同一个缓冲区中不可能有不同的foldmethod类型.Vim如何知道在同一缩进级别有一些评论与您想要视为具有不同(更高编号)级别的其他文本?
我确信你可以通过将foldmethod设置为'expr'来实现你想要的.这是在Vim中进行折叠的最灵活方式,但可能会变得复杂(和/或缓慢),具体取决于您的需求.不过,我认为它对你的用例来说相当容易.
首先,在vimrc或vimscripts中的某个位置,您需要确保为相关文件类型定义了foldexpr.
set foldexpr=MyFoldLevel(v:lnum)
set foldmethod=expr
" and for last code example
let b:previous_level = 0
Run Code Online (Sandbox Code Playgroud)
然后你必须充实你的foldexpr函数,以便它以一种导致你想要的行为的方式分配级别.类似下面的代码可能接近于每个注释行都有前缀符号(即,不是你的情况),但我希望它需要一些调整. h: fold-expr是寻求帮助的好地方:
function! MyFoldLevel(linenum)
" assign levels based on spaces indented and tabstop of 4
let level = indent(a:linenum) / 4
if getline(a:linenum) =~ [put line-based comment prefix pattern here]
let level = 20
endif
endfunction
Run Code Online (Sandbox Code Playgroud)
需要进行修改,以便按照您希望的方式为注释开始和结束标记之间的行分配更高级别:
function! MyFoldLevel(linenum)
let linetext = getline(a:linenum)
if linetext =~ [put line-based comment prefix pattern here]
let level = 20
elseif linetext =~ '^\s*/\*'
let level = 20
elseif linetext =~ '^\s*\*/'
let level = 21
else
if b:previous_level == 20
let level = 20
else
"assuming code is space-indented with tabstop of 4
let level = indent(a:linenum) / 4
endif
endif
let b:previous_level = level
return level
endfunction
Run Code Online (Sandbox Code Playgroud)
我不希望我写的foldmethod函数完全按照书面形式工作.但他们确实指出了可行的方法.
请注意,对注释使用"20"级别只是允许它们折叠的任意级别,而所有(可能是较低级别的)缩进代码都是可见的.最后一行评论部分的"21"只是为了区别于前面的20级评论,以便知道下一行应该被视为常规代码行.
此外,当'zc'和'zo'等关键操作设置为远高于周围代码的级别时,它们在评论时将无法正常工作.想要使用直接命令:set foldlevel=21来显示所有注释行.
不漂亮,我希望它可以简化一点,但我认为这是你想要的东西.
实际上,考虑到这一点,我认为你会希望任何评论块的第一行处于同一级别,就像它是非评论行一样,只有同一块中的后续评论行需要更高级别让他们"折叠"到起始评论行.在我给出的代码中,如果它工作或接近工作,我认为vim将折叠前面的非注释行后面的所有注释行,这不是你想要的,但我很遗憾没有更多是时候投入这个小谜题了...我已经完成了这种自定义折叠很多次,并且在获得我想要的东西时总是会有一些试验和错误.