我喜欢Atom和Sublime Text处理行折叠的方式,其中每个折叠的第一行都是可见的(语法高亮显示完整),并且在该行的末尾附加了一个标记来指示折叠。 br />
请参见下面的屏幕快照,比较Vim的缩进折叠(顶部)和Atom的缩进折叠(底部):

Vim每次折叠都指定两行。第一行用作标题,第二行描述有关折页的一些信息(折页内的行数和文本)。

Atom仅使用一行,并在标记处使用小标记表示折页的行尾,以及添加到左侧行号的颜色。 Atom的折叠样式使用的屏幕空间更少,但仍可以传达我真正需要的所有信息。

我偏爱Atom的折叠样式。在我看来,尤其是当连续列出多个方法或属性时(如上面的屏幕截图),它看起来更干净,更一致。

有没有办法大致估算Vim中Atom的折叠样式?

评论

我认为这是因为您的折叠实际上并不是从包含开口括号的行开始的。 Vim仅在折叠开始的行上使用折叠文本。例如,请参见C中的括号位置如何影响它:imgur.com/3h70dPf,wfCLPm7

但这是Python,不涉及括号(来自__future__ import括号)...您如何配置折叠功能?并且可以粘贴此代码段(或其他演示问题的代码段)吗? Vim可以折叠成一行,但是正如一位大师所说,您的折叠起得晚了。

@Carpetsmoker括号仅用于说明折叠开始的位置。可以在Haskell上看到相同的效果。

#1 楼

在Vim中,两行相对于一行

折叠中的所有行都将折叠为单行,然后'foldtext'选项确定这些行的提要(通常是破折号,折线的数量) ,以及来自第一行(或所有行)的内容。)在您的示例中,在Vim中,仅{...}参数块本身被折叠;上面的行(使用参数)不是折叠的一部分。相反,在另一个编辑器中,使用参数的那一行属于该折叠,而其折叠文本(使用Vim术语)是该行的内容以及附加的标记。

Adapting

在Vim中,可以通过不同的方式生成折叠(请参阅:help fold-methods),并且取决于缓冲区的'filetype'。将上述行包含在折叠中的难度取决于此;用:setlocal foldmethod?检查。缩进折叠后,您将无法影响任何东西。您必须切换到另一种方法。对于语法折叠,这将意味着修改语法定义,并且可能非常棘手。如果使用表达式,将会有更好的运气,但这仍然意味着理解和更改逻辑。 (文件类型插件作者不太可能提供配置来影响此。)

突出显示折叠线的语法

不幸的是,这根本不可能。 Vim始终对整个折叠线使用Folded高亮组。您可以通过:highlight中的~/.vimrc命令对其进行调整,但是语法的个体差异将丢失。

#2 楼

Vim已经将折叠显示为一行。但是,在Vim的indent折叠中,所有具有相同缩进的行都包含在折叠中。因此,在屏幕快照中,您所指的“标题”行(例如,以collection_base_url开头的那一行)不在折叠内。

通过使用Vim的foldexpr foldmethod,您可以实现类似于Atom折叠的功能:

" Finds the indent of a line. The indent of a blank line is the indent of the
" first non-blank line above it.
function! FindIndent(line_number, indent_width)
    " Regular expression for a "blank" line
    let regexp_blank = "^\s*$"

    let non_blank_line = a:line_number
    while non_blank_line > 0 && getline(non_blank_line) =~ regexp_blank
        let non_blank_line = non_blank_line - 1
    endwhile
    return indent(non_blank_line) / a:indent_width
endfunction

" 'foldexpr' for Atom-style indent folding
function! AtomStyleFolding(line_number)
    let indent_width = &shiftwidth

    " Find current indent
    let indent = FindIndent(a:line_number, indent_width)

    " Now find the indent of the next line
    let indent_below = FindIndent(a:line_number + 1, indent_width)

    " Calculate indent level
    if indent_below > indent
        return indent_below
    elseif indent_below < indent
        return "<" . indent
    else
        return indent
    endif
endfunction

set foldexpr=AtomStyleFolding(v:lnum)
set foldmethod=expr


这定义了一个折叠表达式(请参阅:help fold-expr),如下所示:


对于紧缩行之前的行,它返回紧随其后的块的缩进。
对于缩进的行,它返回缩进。 (除以shiftwidth,以便每个缩进级别将返回值增加1)。
对于缩进行块末尾的行,它返回字符串"<N",其中N设置为缩进。这告诉Vim那条线的N级折叠完成了。

Update

@alxndr在评论中询问是否可以扩展它以将Ruby的end包含在其中褶皱。您可以先将" Calculate indent level部分替换为以下内容:

if indent_below > indent
    return indent_below
elseif getline(a:line_number) =~ '^\s*end\s*$'
    return "<" . (indent + 1)
else
    return indent
endif


就目前而言,这不是最可靠的解决方案(例如,如果end语句将失败在同一行上,用分号隔开)。您可以调整正则表达式和周围的代码来解决此问题,但是由于您现在处在解析文件实际语法的领域内,因此我认为在找到一个好的解决方案之前,事情可能会变得更加复杂。 />

评论


很棒的方法。可以将这个答案推广到还可以说出Ruby,并且末端要突出以完成一个块吗?

– alxndr
15年2月24日在18:29

@alxndr我通过一些讨论来编辑答案。

–丰富
16年7月15日在13:07

@Rich:我还发现Sublime文本折叠只在行尾显示一个标记...作为折叠文本块的符号,非常有用,并且比在vim中必须突出显示整个文本块的第一行要少分散注意力。我尝试使用vim的默认折叠行为在上面进行折叠,简单不起作用。如何使用python在文本块的第一行末尾打上一个标记呢?我应该打开一个新问题吗?我只是再次测试您的弃牌率,使用缩进线确实可以很好地工作。超级谢谢。

–图恩·范(Tuyen Pham)
18年5月5日在5:18



这真太了不起了!我一直在寻找可以进行组织模式(如折叠)的东西,这很有帮助!

–priomsrb
19年4月2日在2:09