2011-09-29 15 views
12

vimで自動的にルビソースファイルを折りたたむ方法はありますか?定義されているレベルに関係なくメソッドレベルでフォールドするだけですか?vimでの自動​​ルビ折り畳み

私が持っているときにそれが倍になります。

class MyClass 
    def method 
    ... 
    end 
end 

だけでなく、私が持っているとき:

module FirstModule 
    module SecondModule 
    class MyClass 
     def method 
     ... 
     end 
    end 
    end 
end 

を私はfoldmethod =構文と様々倍のレベルを試してきましたが、それはかかりません。メソッドが定義されている深さを考慮する必要があります。

また、私は方法の中で折り畳まれることを望んでいません(ブロック、ブロックなどの場合)。

私はfoldmethod = exprが私の最善の策だと思っていますが、折り畳み表現がどのように機能しているのか把握できていませんし、vimのヘルプはあまり啓発されていません。

答えて

11

exprメソッドの使用についてのあなたの勘違いは、間違いないと思います。

ファイルの構文構造を使用して、自分自身のsyntaxスタイルの折り畳みをjury-rigすることができます。

function! RubyMethodFold(line) 
    let line_is_method_or_end = synIDattr(synID(a:line,1,0), 'name') == 'rubyMethodBlock' 
    let line_is_def = getline(a:line) =~ '\s*def ' 
    return line_is_method_or_end || line_is_def 
endfunction 

set foldexpr=RubyMethodFold(v:lnum) 

いくつかの注意点:私の.vimrc生産期待される動作では、次のsynIDへの最後の引数は0または1するかどう

私はわかりません。これは、最上位の透過情報またはの不透明情報要素が指定された場所にあるかどうかを判断する引数です。透明な要素がない場合、引数は効果がありません。私が試した簡単な例では、それは問題を引き起こさなかったが、そうかもしれない。

line_is_def正規表現があまりにも寛大すぎる可能性があることにも注意してください。この状況で-1を返すほうが良いかもしれないので、正規表現にマッチする行は、それが折り畳まれたメソッドブロックのすぐ隣にあるときにのみ折り畳まれます。より限定的な正規表現も使えます。

あなたが嫌悪感を感じている場合は、これを拡張してrubyClassrubyModule要素の別の折り畳みレベルを返すこともできます。

あなたがそのルートを下ることに決めた場合、シンタックスエレメントとハイライトのイントロスペクションには、useful custom functions in my .vimrcがあります。これはあなたのために働くなら、私に知らせてください

nnoremap g<C-h> :echo GetSynInfo()<CR> 

てください:そうのような迅速な使用のためのキーバインドにマッピングされたとき、彼らが最も便利です!把握するのは楽しいことでした。また、それは価値があるため、:help 'foldexpr'は細部には明るいですが、:help 'fold-expr'ははるかに役立ち、さらにいくつかの例があります。

+2

これはすばらしい答えです。これは適切な解決策、または少なくとも私が欲しいところへ行くための出発点です。私はそれが今日後でどのように機能し、答えを受け入れるかをテストする予定です。また、あなたのvimrcは素晴らしい学習リソース、特にあなたが定義したすべての機能のように見えます。ありがとう。 – adivasile

+0

あなたは大歓迎です!ハッピー・ヴィヴィング! –

+0

私はこれがあなたのためにどうやって動いたか知りたいと思います! –

1

zOコマンドを使用すると、メソッド内で折り畳まれた解決策を手に入れることができます。 zOを再帰的に開きます。zoの代わりに使用すると、メソッド内の何も折りたたまれていないかのようになります。また、気分が悪い場合はをzOに変更することもできます。

+0

実際に役立つだろうが、主な問題は依然として残っています。メソッドを自動的に折り畳むことです。 – adivasile

3

あなたはすでにシンタックスハイライトを持っている場合は特に、これでより良い運を持っていることがあります。

これは、これはまた、折り畳みに大きなVIMcastであるあなたの〜/ .vimrcと

 
"" Enable folding based on syntax rules 
set foldmethod=syntax 

"" Adjust the highlighting 
highlight Folded guibg=grey guifg=blue 

"" Map folding to Spacebar 
nnoremap za 

に行くだろう:http://vimcasts.org/episodes/how-to-fold/

4

マックス・カントールのソリューションに変更を加えて、完全に動作し、どこにあるかにかかわらずdefメソッド(endキーワードを含む)とドキュメント(= begin = end)ブロックを折り畳みます

function! RubyMethodFold(line) 
    let stack = synstack(a:line, (match(getline(a:line), '^\s*\zs'))+1) 

    for synid in stack 
    if GetSynString(GetSynDict(synid)) ==? "rubyMethodBlock" || GetSynString(GetSynDict(synid)) ==? "rubyDefine" || GetSynString(GetSynDict(synid)) ==? "rubyDocumentation" 
     return 1 
    endif 
    endfor 

    return 0 
endfunction 

set foldexpr=RubyMethodFold(v:lnum) 

set foldmethod=expr 

構文情報を出力するためのヘルパーメソッドのおかげでマックスカンターに感謝します。

は私が線でこのラインを説明してみましょう:

最も重要な行は、それがラインの構文要素のveriousレベルのスタックを取得する第二のラインになります。 その前に空白またはタブがあるdef methodnameのような行がある場合、最初の空白以外の文字でスタックが常に得られます。 Max Cantorの解決策の問題は、コードが行の最初の列にある最も低い構文要素を出力するだけなので、常にrubyContantのような要素が返されることです。

match(getline(a:line), '^\s*\zs')を使用することで、最初の空白以外の文字の列にカーソルを移動することができ、より正確なスタックの画像を取得できます。 +1は一致インデックスがゼロであるためです

残りの部分はGetSynInfoメソッドと似ています。ここでは、スタックをループして、必要な要素と一致させ、1がすべて同じ折りたたみレベルにあり、残りが0になるように返します。

そして、それはそれだ、唯一のルビーは、メソッドを定義折り畳まれる作業折りたたみ式expr機能:)

は素敵な一日をお楽しみくださいと持っています!

+1

あなたの答えは有望ですが、残念ながら何も起こっていませんでした。解決策は、これらの関数が定義されていないようです: 'GetSynString'と' GetSynDict'。あなたはそれらを提供するために気をつけますか?ありがとう –

1

ルビーで簡単な方法の折りたたみのためにvim-ruby-foldプラグインを作った。私は人々に役立つことを願っています

関連する問題