【问题标题】:How to fold to a specific level in Vim across an entire file at once?如何一次在整个文件中折叠到 Vim 中的特定级别?
【发布时间】:2024-01-21 20:18:01
【问题描述】:

我想在 Vim 中按一个按钮并折叠所有代码,以便只显示特定(和可变)缩进级别的代码。例如,当我只想查看方法名称而不是它们的缩进例程时,这非常有用。

Vim: Fold top level folds only”问题有一个缩进级别的解决方案,但每次更改级别时都需要设置环境。

当我的光标处于缩进级别(例如级别 2)时,我希望整个文件在所有方法中都折叠到该缩进级别。

这是内置在 Vim 中的某个地方吗?有没有人知道一个很好的插件可以做到这一点?

【问题讨论】:

  • 建议:看zm(多折叠)和zr(少折叠);还有zM/zR for '一路'

标签: vim


【解决方案1】:

配置折叠由缩进定义:

:setl foldmethod=indent

并尝试以下命令:

:let &l:foldlevel = indent('.') / &shiftwidth

要快速访问此命令,请为它创建一个映射,如下所示:

:nnoremap <silent> <leader>z :let&l:fdl=indent('.')/&sw<cr>

【讨论】:

  • 对于经验不足的 vim 用户,您能解释一下如何访问它吗?另外,这三个命令都进入 vimrc 了吗?
【解决方案2】:

无需插件,Vim 内置。

'foldlevel'(或更短的'fdl')和'foldnestmax'('fdn')似乎是我们正在寻找的。您只需在 .vimrc 文件中设置 'foldmethod'(或更短的 'fdm')和 'foldnestmax'(或 'fdn'):

set foldmethod=indent foldlevelstart=2 foldnestmax=2

或较短的版本:

set fdm=indent fdls=2 fdn=2

然后您可以使用直接命令更改折叠级别:zm 或 zr。

【讨论】:

    【解决方案3】:

    因为当 foldmethod 为 expr 时 foldnestmax 不适用,所以当我遇到您的问题时,我寻找了其他东西。这是我想出的,毫无疑问可以改进:

    function! <sid>CloseFoldOpens(opens_level)
        let lineno = 2
        let last = line("$")
        while lineno < last
            if foldclosed(lineno) != -1
                let lineno = foldclosedend(lineno) + 1
            elseif foldlevel(lineno) > foldlevel(lineno - 1)
            \ && foldlevel(lineno) == a:opens_level
                execute lineno."foldclose"
                let lineno = foldclosedend(lineno) + 1
            else
                let lineno = lineno + 1
            end
        endwhile
    endfunction
    nnoremap <silent> z1 :%foldclose<cr>
    nnoremap <silent> z2 :call <sid>CloseFoldOpens(2)<cr>
    nnoremap <silent> z3 :call <sid>CloseFoldOpens(3)<cr>
    nnoremap <silent> z4 :call <sid>CloseFoldOpens(4)<cr>
    nnoremap <silent> z5 :call <sid>CloseFoldOpens(5)<cr>
    

    我更喜欢编号的地图,但对于你的基于当前行的缩进,这些行的内容:

    nnoremap <silent> z. :call <sid>CloseFoldOpens(foldlevel('.'))<cr>zv
    

    【讨论】:

      最近更新 更多