【问题标题】:Context sensitivity in commentstring注释字符串中的上下文敏感性
【发布时间】:2012-03-05 15:42:22
【问题描述】:

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

是否可以设置commentstring 以使// 字符仅在它们尚未出现在行上时才添加?

【问题讨论】:

    标签: vim folding


    【解决方案1】:

    根据: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
    

    与之前版本的循环不同,两者的处理顺序 行很重要:应首先添加结束标记线,如果 必要的,因为为开始标记插入一行会使 以下几行更改其编号。

    【讨论】:

    • 非常好。我唯一要改变的是在 else 子句中使用 setline 而不是 append 来保持标记在同一行。
    • @WilliamPursell:我认为你是对的:最好将此行为设为自定义zf 命令的默认行为,因为它符合内置zf 的行为。答案会相应更新。
    猜你喜欢
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    相关资源
    最近更新 更多