如何为Vim编写一个使用注释结构的foldexpr?

时间:2014-06-21 16:38:53

标签: vim folding

是否有可能构建一个foldexpr来检测以下匹配\n\n"\s[A-Z][A-Z].*\n作为第一级折叠的开始,并且这些匹配\n"\s[A-Z][a-z].*\n作为二级折叠的开始?当然,最接近的\n\n\n标志着第一级折叠的结束,然后\n\n将关闭第二级折叠。

或者我错过了什么?

(我当然知道{{{个标记,我在文件中添加其他标记似乎不对... ...

1 个答案:

答案 0 :(得分:1)

你不可能在一行中做到这一点(至少,不容易或不清楚)。你想写一个函数。

您的函数将无法使用单个getline()和正则表达式比较,因为getline()只返回一行,并且您希望在开始/结束字符串中包含多行。但是,您可以使用多个getline()调用并分别比较每一行。

要在当前现有折叠的同一级别启用新折叠,您需要返回字符串"> 1"或"> 2"。对于结束折叠,最简单的方法就是设置一个显式级别(使用字符串"< 2"等有时会对我意外行为)。有关可能的返回值,请参阅:help fold-expr。了解函数中最后一行的foldlevel可能很有用。为此,请使用函数foldlevel()

这是一个我认为可以满足您要求的例子,但如果它实际上并不是您想要的,您可能需要清理它。加载脚本,获取脚本,它可以将自己用作测试数据:

fun! FoldSomething(lnum)
  let line1=getline(a:lnum)
  let line2=getline(a:lnum+1)
  if line1=~'^$'
    if line2=~#'^"\s[A-Z][A-Z]'
      return ">1"
    elseif line2=~'^$'
      return 0
    elseif foldlevel(a:lnum-1)==2
      return 1
    endif
  elseif line1=~#'^"\s[A-Z][a-z]'
    return ">2"
  endif
  return "="
endfun
set foldexpr=FoldSomething(v:lnum)
set foldmethod=expr
set foldcolumn=3
finish


" AA level 1 fold
" This is a level 2 fold
Here is some stuff under the fold.
It should be part of the level 2.

This isn't in the level 2.
I guess that makes it just part of the level 1.

" This is another
" level 2 fold.
" Watch out!
" This is 2 level 2 folds.


" BB another level 1 fold
" starts here.
"



This line shouldn't be folded at all.

That's because there were so many empty lines before.