2011-09-29 4 views
12

vim에서 자동으로 루비 소스 파일을 접을 수 있도록 설정할 수있는 방법이 있습니까?하지만 정의 된 레벨에 관계없이 메소드 레벨에서만 폴드 할 수 있습니까?vim에서 자동 루비 폴딩

그래서 내가 가지고있는 경우는 배됩니다

class MyClass 
    def method 
    ... 
    end 
end 

뿐만 아니라 내가 가지고있는 경우 :

나는 foldmethod = 구문과 다양한 배 수준으로 실험 한
module FirstModule 
    module SecondModule 
    class MyClass 
     def method 
     ... 
     end 
    end 
    end 
end 

하지만 걸릴하지 않습니다 메소드가 정의 된 깊이를 고려하십시오.

또한 메서드 내에서 아무 것도 (블록, 각 블록 등) 접기를 원하지 않습니다.

foldmethod = expr이 최선의 방법 일 것이라고 생각합니다. 그러나 fold expression이 어떻게 작동하는지 파악할 수 없었고, 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'은 훨씬 도움이되며 맨 위에 몇 가지 예가 있습니다. http://vimcasts.org/episodes/how-to-fold/ :

이것은 당신의 ~/.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 

이것은 또한 폴딩에 큰 VIMcast입니다에 갈 것 :

+2

이것은 훌륭한 답변입니다. 올바른 해결책이거나, 내가 원하는 곳으로 가기에 좋은 출발점이 될 것 같습니다. 오늘 나중에 어떻게 작동하는지보고 테스트 해보고 답변을 수락합니다. 또한 vimrc는 훌륭한 학습 자원, 특히 사용자가 정의한 모든 기능과 비슷합니다. 감사. – adivasile

+0

당신은 아주 환영합니다! 행복한 vimming! –

+0

나는 이것이 어떻게 당신을 위해 잘되었는지 알고 싶습니다! –

1

zO 명령을 사용하여 메서드 내에서 접히는 솔루션을 사용하지 못하게 될 수도 있습니다. zO은 반복적으로 열어이되므로 zo 대신 사용하면 메서드 내 아무 것도 접혀지지 않은 것처럼 보입니다. 아프다고 느끼는 경우 을 zO으로 다시 매핑 할 수도 있습니다.

+0

실제로 도움이 될 수 있지만 주요 문제는 여전히 남아 있습니다. 자동으로 접히는 방법입니다. – adivasile

3

당신은 이미 구문 강조를 가지고 특히,이 더 나은 행운을 가질 수있다

4

Max Cantor의 솔루션을 변경했는데 완벽하게 작동합니다. 클래스 또는 들여 쓰기 위치에 관계없이 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 

구문 정보를 인쇄하는 도우미 메서드 덕분에 Max Cantor에게 감사드립니다.

날 선으로이 라인을 설명하자

가장 중요한 라인은 라인에 구문 요소의 verious 수준의 스택을 얻는 두 번째 줄 것입니다. 그래서 공백 또는 탭이있는 def methodname과 같은 줄이 있으면 첫 번째 비 공백 문자에서 항상 스택을 가져옵니다. Max Cantor의 해결책의 문제는 코드가 줄의 첫 번째 열에있는 가장 낮은 구문 요소 만 출력하므로 항상 신경 쓰이지 않는 "rubyContant"와 같은 요소를 무작위로 반환한다는 것입니다.

따라서 match(getline(a:line), '^\s*\zs')을 사용하면 커서를 첫 번째 비 공백 문자의 열로 이동할 수 있으므로 더 정확한 스택 사진을 얻을 수 있습니다. +1은 일치 색인이 생성되기 때문에 +1합니다.

나머지는 GetSynInfo 메서드와 비슷합니다.이 메서드는 스택을 반복하고 원하는 요소를 일치시킨 다음 1을 반환하므로 모두 동일한 접기 레벨에 있고 나머지 0은 0입니다.

그리고 그게 다입니다 만 :) 루비 방법을 정의 배

가 즐기고 좋은 하루 되세요하는 작업 접는 EXPR 기능!

+1

당신의 대답은 유망 해 보이지만 불행히도 아무 일도 일어나지 않았습니다. 이 솔루션은'GetSynString'과'GetSynDict'와 같은 함수를 정의하지 못하는 것 같습니다. 그들을 제공 해주시겠습니까? 감사 –

1

나는 루비에서 간단한 방법 접기를 위해 vim-ruby-fold 플러그인을 만들었습니다. 사람들에게 도움이되기를 바랍니다.