commentstring中的上下文敏感性

时间:2012-03-05 15:42:22

标签: vim folding

手动设置折叠时,如果可以以上下文敏感的方式设置commentstring,则会很方便。考虑这种情况,语言使用BCPL样式的注释标记(即注释以//开头并以换行符结束),可视块的第一行包含注释,最后一行不包含注释。目前,如果commentstring设置为//%s,则当//用于创建折叠时,多余的zf字符将附加到第一行。

是否可以设置commentstring以便仅在//字符尚未显示在该行上时添加{{1}}个字符?

1 个答案:

答案 0 :(得分:1)

根据:help fold-create-marker,自动折叠标记插入 在以下情况下无法正常工作:

  
      
  • 该行已包含带有级别编号的标记。然后Vim没有   知道该怎么做。
  •   
  • 在附近折叠使用他们的标记中的等级编号,这会妨碍他们。
  •   
  • 该行位于注释中,commentstring不为空且嵌套   评论不起作用。例如,使用C:在里面添加/* {{{ */   评论将截断现有评论。
  •   

因此,无法通过修改默认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模式匹配。对于每一个 两个匹配,它在第一个找到的内部插入相应的标记 评论,在其文本的最开始。否则,标记是 根据{{​​1}}模板进行装饰,并在最后添加 这条线。

如果在后一种情况下,最好将标记分开, 可以改变for循环,如下所示。

commentstring

与循环的先前版本不同,处理两者的顺序 线很重要:首先应添加结束标记线,如果 必要的,因为为开始标记插入一行会改变 以下几行改变了他们的数字。