AtomまたはSublime Textと同様に、vimの折りたたみを1行に折りたたみます


13

私は、AtomとSublime Textが行の折り畳みを処理する方法が好きです。各折り畳みの最初の行が表示され(構文の強調表示が完了)、折り畳みを示す行の末尾にマーカーが追加されます。

Vimのインデントフォールディング(上)とAtomのインデント(下)を比較した以下のスクリーンショットを参照してください。VimとAtomコードの折りたたみ

Vimは各フォールドに2行を割り当てます。1行目は見出しとして機能し、2行目は折り畳みに関するいくつかの情報(折り畳み内の行数とテキスト)を説明します。

Atomは1行のみを使用し、行の終わりに小さなマーカーを使用して、左側の行番号に追加された色とともに折り目を示します。Atomの折りたたみスタイルは、使用する画面領域が少なくなりますが、それでも本当に必要なすべての情報を伝えます。

私はAtomの折りたたみスタイルには不満です。私の意見では、特に上記のスクリーンショットのように複数のメソッドまたは属性を連続してリストする場合は、よりクリーンで一貫しているように見えます。

VimでAtomの折りたたみスタイルを大まかに概算する方法はありますか?


1
私は、あなたの折り目が実際には開き括弧を含む行で始まっていないからだと思います。Vimは、折り畳みが始まる行の折り畳みテキストのみを使用します。たとえば、Cでのブレースの配置がどのように影響するかを参照してください:imgur.com/3h70dPf,wfCLPm7
muru

しかし、これはPythonであり、中括弧は含まれていません(from __future__ import braces)...折りたたみをどのように構成しましたか?また、このコードスニペット(または問題を示す別のコードスニペット)を貼り付けることはできますか?Vimは1行に折り畳まれますが、muruが述べたように、折り畳みは行を遅く開始します。
マーティントゥールノイジ

@Carpetsmoker中括弧は、折り畳みの開始位置を示すためだけのものです。同じ効果が、たとえばHaskellでも見られます。
ムル

@MikeHearn以前の答えは完全に間違っていました。問題の解決策を含めるように更新しました。
リッチ

回答:


12

2行と1行

Vimでは、フォールド内のすべての行が1行に折りたたまれ、'foldtext'オプションはそれらの行の概要を決定します(通常、ダッシュ、折りたたまれた行の数、最初の(またはすべての)行のコンテンツ)。

あなたの例では、Vimでは{...}パラメーターブロックのみが折りたたまれています。上記の行(パラメーターを使用)は、フォールドの一部ではありません。対照的に、他のエディターでは、パラメーターを使用するその行は折り畳みに属し、その折り畳みテキスト(Vimの用語を使用するため)は、その行の内容と追加されたマーカーです。

順応

Vimでは、折り畳みはさまざまな方法で生成でき(「参考文献」を参照:help fold-methods)、'filetype'バッファーの種類によって異なります。上記の行を折り目に含めることの難しさは、それによって異なります。で確認してください:setlocal foldmethod?。ではインデント折りたたみ、あなたが影響を与えることができるものは何もありません。別の方法に切り替える必要があります。構文の折りたたみについては、構文定義を適応させることを意味し、非常に注意が必要です。が使用されている場合は幸運がありますが、それでもロジックを理解して変更することを意味します。(filetypeプラグインの作成者がこれに影響する構成を提供した可能性は低いです。)

折れ線の構文強調表示

残念ながらそれはまったく不可能です。Vimは常にFolded、折り畳まれた行全体にハイライトグループを使用します。の:highlightコマンドを使用してそれを微調整できます~/.vimrcが、構文の個々の区別は失われます。


5

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、セミコロンの後、ステートメントが同じ行にある場合は失敗します)。これに対処するために正規表現と周囲のコードを微調整することもできますが、ファイルの実際の構文を解析する領域内にいるので、良い解決策が得られる前に事態はさらに複雑になると思います。


素晴らしいアプローチ。この答えはend、ブロックを終了するようにアウトデントされたRubyを処理するためにも一般化できますか?
alxndr

1
@alxndrいくつかの議論で答えを編集しました。
リッチ

@Rich:また...、折りたたまれたテキストブロックのシンボルとして行末のマークのみを表示するSublimeテキストフォールドも非常に便利であり、vimのようにテキストブロックの最初の行全体を強調表示するよりも注意散漫が少なくなります。上記の折り畳みをvimのデフォルトの折り畳み動作で試してみましたが、simpleは機能しません。Pythonでテキストブロックの最初の行の最後にマークを付ける折り目を付ける方法は?新しい質問を開く必要がありますか?折り目をもう一度テストしますが、実際にはインデント行で非常にうまく機能します。本当にありがとう。
チュエンファム

これは素晴らしいです!私は、折りたたみのような組織モードを行うものを探していましたが、これは非常に役立ちます!
priomsrb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.