Vim已经将折叠显示为一行。但是,在Vim的indent
折叠中,所有具有相同缩进的行都包含在折叠中。因此,在屏幕截图中,您所指的“标题”行(例如,以开头的那一行collection_base_url
)不在折叠内。
通过使用Vim可以实现类似于Atom的折叠方式foldexpr
foldmethod
:
" 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
这定义了一个fold表达式(请参阅参考资料:help fold-expr
),如下所示:
- 对于紧缩行之前的行,它返回紧随其后的块的缩进。
- 对于缩进的行,它返回缩进。(除以shiftwidth,因此每个缩进级别将返回值增加1)
- 对于缩进行的末尾的行,它返回一个string
"<N"
,其中N设置为缩进。这告诉Vim 该行完成 N级折叠。
更新资料
@alxndr在评论中询问是否可以扩展它以将Ruby的outdented 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
语句位于分号后的同一行,它将失败。)您可以调整正则表达式和周围的代码以解决此问题,但是由于您现在处在解析文件实际语法的领域内,因此我认为在找到一个好的解决方案之前,事情可能会变得更加复杂。