根据:help fold-create-marker,自动折叠标记插入
在以下情况下无法正常工作:
- 该行已包含一个带有级别编号的标记。 Vim 然后没有
知道该怎么做。
- 附近的折叠在其标记中使用级别编号,这会妨碍您。
- 该行在注释内,
commentstring 不为空且嵌套
cmets 不工作。例如使用 C:在里面添加 /* {{{ */
评论将截断现有评论。
因此,无法通过修改默认 zf 行为来更改
commentstring 设置。
但是,可以创建 zf 命令的自定义版本,
会考虑到开始或结束(或两者)的行
折叠可能有 cmets。例如,考虑以下映射,一个
用于通过视觉选择标记折叠,另一个用于与动作一起使用
命令。
nnoremap <silent> <leader>zf :set opfunc=CreateMarkerFold<cr>g@
vnoremap <silent> <leader>zf :<c-u>call CreateMarkerFold(visualmode(), 1)<cr>
function! CreateMarkerFold(vt, ...)
let range = map(['[<', ']>'], 'line("''".v:val[a:0])')
let mark = split(&foldmarker, ',')
let pat = escape(&commentstring, '\')
let pat = '\V' . substitute(pat, '\\\@<!%s', '\\zs\\ze\\.\\{-}', '')
for i in [1, 0]
let line = getline(range[i])
if line =~ pat
let line = substitute(line, pat, escape(mark[i], '\'), '')
else
let line .= printf(&commentstring, mark[i])
endif
call setline(range[i], line)
endfor
endfunction
两个映射都遵循相同的例程。在添加开始和之前
结束折叠标记,它分别检查第一个和最后一个是否
要折叠的块的行与commentstring 模式匹配。对于每一个
两个匹配的,它在第一个找到的内部插入相应的标记
评论,在其文本的开头。否则,标记为
根据commentstring模板装饰并添加在末尾
行。
如果在后一种情况下最好将标记单独放在一行上,
如下所示,可以更改 for 循环。
for i in [1, 0]
let line = getline(range[i])
if line =~ pat
let line = substitute(line, pat, escape(mark[i], '\'), '')
call setline(range[i], line)
else
call append(range[i] - !i, printf(&commentstring, mark[i]))
endif
endfor
与之前版本的循环不同,两者的处理顺序
行很重要:应首先添加结束标记线,如果
必要的,因为为开始标记插入一行会使
以下几行更改其编号。