Vimは既に折り目を1行で表示しています。ただし、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
これは、:help fold-expr
次のように折り畳み式(を参照)を定義します。
- インデントされた行の直前の行については、後続のブロックのインデントを返します。
- インデントされた行の場合、インデントを返します。(シフト幅で除算されるため、インデントの各レベルは戻り値を1ずつ増やします)
- インデントされた行のブロックの最後の行については、文字列を返します
"<N"
。ここで、Nはインデントに設定されます。これは、レベルNのフォールドがその行で終了することをVimに伝えます。
更新
@alxndrは、コメントend
内で、Rubyのアウトデントされたをフォールド内に含めるように拡張できるかどうかを尋ねます。" 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
、セミコロンの後、ステートメントが同じ行にある場合は失敗します)。これに対処するために正規表現と周囲のコードを微調整することもできますが、ファイルの実際の構文を解析する領域内にいるので、良い解決策が得られる前に事態はさらに複雑になると思います。