我目前正在为Vim开发一个用于管理清单的插件。
我目前在语法文件中使用“:setlocal foldmethod = indent”来处理每个核对表文档中的所有折叠。但是,我想创建一个更灵活的折叠功能,并且不会依赖线的缩进来确定它是否折叠。
以下是一个示例清单:
+ Parent
* Child
* Child
* Child
当用户在“+ Parent”行上按<leader>
vv时,它会折叠下面的行,因为它们缩进了一个级别。这个问题是折叠方法会粘在其他缓冲区周围并折叠不需要折叠的线条。
以下是我到目前为止处理它的方法:
function! FoldLines()
let l:line = getline(line(".") + 1)
" If next line is a child
if match(l:line, '^\s*\*') >= 0
" Loop until blank line is found, and store line numbers in a list
endif
" Select lines from list and fold
endfunction
我不知道如何处理循环和折叠。有什么建议吗?
更新
嗯,karategeek6的解决方案在某种程度上有效,但我没有提到我的插件也会切换清单项目。
示例:
+ Parent
× Child - Toggled
* Child - Standard
我可能错了,但我不认为foldexpr能够在开头处理带有*和×的行。
我试过了:
set foldexpr=strlen(substitute(substitute(getline(v:lnum),'\\s','',\"g\"),'[^[*|×]].*','',''))
但这似乎也不起作用。
答案 0 :(得分:2)
这听起来像你希望它通过表达式折叠。根据{{3}},在表达式中,您可以使用表达式设置每一行的折叠级别。用户手册提供了一个我认为可以根据您的需求进行调整的示例。
:set foldmethod=expr
:set foldexpr=strlen(substitute(substitute(getline(v:lnum),'\\s','',\"g\"),'[^*].*','',''))
您可以在用户手册中阅读更多关于示例的内容,但简而言之,它将折叠级别设置为等于前导'*'的折叠级别,而不考虑空格。
希望这正是您正在寻找的,或者可以指向正确的方向。通过表达式折叠时要记住的关键方面是,您要决定每条线的折叠级别,而不是折叠哪条线。
答案 1 :(得分:1)
好吧,好像我找到了一个解决方案。我最终使用了这个:
setlocal foldlevel=0
setlocal foldmethod=expr
setlocal foldexpr=FoldLevel(v:lnum)
function! FoldLevel(linenum)
let linetext = getline(a:linenum)
let level = indent(a:linenum) / 4
if linetext =~ '^\s*[\*|×]'
let level = 20
endif
return level
endfunction