当手动设置折叠时,如果可以以上下文敏感的方式设置commentstring,这将是很方便的。考虑这样的情况:语言使用BCPL样式的注释标记(即注释以//开头并以换行符结尾),可视块的第一行包含注释,而最后一行不包含注释。目前,如果commentstring设置为//%s,则在使用//创建文件夹时,冗余的zf字符将附加到第一行。
是否可以将commentstring设置为仅当//字符尚未出现在行中时才添加这些字符?
发布于 2012-03-06 09:49:30
根据:help fold-create-marker的说法,在以下情况下,自动折叠标记插入无法正常工作:
/* {{{ */将截断现有注释。因此,无法通过修改zf设置来更改默认commentstring行为。
但是,可以创建自定义版本的zf命令,该命令将考虑到文件夹的开始行或结束行(或这两个行)可能具有注释。例如,考虑以下映射,一个用于通过视觉选择标记折叠,另一个用于与运动命令一起使用。
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与前一个版本的循环不同,处理这两行的顺序很重要:如果需要,应该首先添加结束标记行,因为插入一行作为开始标记将使后面的行改变其编号。
https://stackoverflow.com/questions/9569502
复制相似问题