请参见下面的屏幕快照,比较Vim的缩进折叠(顶部)和Atom的缩进折叠(底部):
Vim每次折叠都指定两行。第一行用作标题,第二行描述有关折页的一些信息(折页内的行数和文本)。
Atom仅使用一行,并在标记处使用小标记表示折页的行尾,以及添加到左侧行号的颜色。 Atom的折叠样式使用的屏幕空间更少,但仍可以传达我真正需要的所有信息。
我偏爱Atom的折叠样式。在我看来,尤其是当连续列出多个方法或属性时(如上面的屏幕截图),它看起来更干净,更一致。
有没有办法大致估算Vim中Atom的折叠样式?
#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
评论
我认为这是因为您的折叠实际上并不是从包含开口括号的行开始的。 Vim仅在折叠开始的行上使用折叠文本。例如,请参见C中的括号位置如何影响它:imgur.com/3h70dPf,wfCLPm7但这是Python,不涉及括号(来自__future__ import括号)...您如何配置折叠功能?并且可以粘贴此代码段(或其他演示问题的代码段)吗? Vim可以折叠成一行,但是正如一位大师所说,您的折叠起得晚了。
@Carpetsmoker括号仅用于说明折叠开始的位置。可以在Haskell上看到相同的效果。