2011-09-29 14 views
12

में स्वत: रूबी फोल्डिंग क्या कोई तरीका है कि मैं स्वचालित रूप से रूबी स्रोत फ़ाइलों को फोल्ड करने के लिए विम सेट कर सकता हूं, लेकिन केवल उस स्तर के स्तर पर गुना हो सकता है जिस पर उन्हें परिभाषित किया गया है?विम

तो यह गुना होगा जब मेरे पास है:

class MyClass 
    def method 
    ... 
    end 
end 

लेकिन यह भी जब मेरे पास है:

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

मैं साथ foldmethod = वाक्य रचना और विभिन्न गुना के स्तर प्रयोग किया है, लेकिन यह नहीं ले करता है उस गहराई में जहां विधि परिभाषित की गई है।

इसके अलावा मैं विधि के अंदर कुछ भी नहीं चाहता (अगर ब्लॉक, प्रत्येक ब्लॉक, आदि)।

मुझे लगता है कि foldmethod = expr मेरी सबसे अच्छी शर्त होगी, लेकिन मुझे यह पता लगाने में कोई प्रबंधन नहीं हुआ है कि कैसे फोल्ड एक्सप्रेशन काम करते हैं, और विम में सहायता बहुत प्रबुद्ध नहीं रही है।

उत्तर

11

expr विधि का उपयोग करने के बारे में आपका अनुमान, मुझे विश्वास है, सही था!

आप फ़ाइल के सिंटैक्स संरचना का उपयोग अपने स्वयं के syntax-स्टाइल फोल्डिंग को जूरी-रिग करने के लिए कर सकते हैं। मेरी .vimrc उत्पादन अपेक्षित व्यवहार में निम्नलिखित:

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) 

कुछ चेतावनियां:

मैं अगर synID करने के लिए अंतिम तर्क 0 या 1 होना चाहिए यकीन नहीं है। यह तर्क है कि यह निर्धारित करता है कि आपको प्रदत्त स्थान पर शीर्ष पारदर्शी या गैर-पारदर्शी तत्व के लिए सिंटैक्स जानकारी प्राप्त होती है या नहीं। जब कोई पारदर्शी तत्व नहीं होता है, तो तर्क का कोई प्रभाव नहीं पड़ता है। छोटे उदाहरण में मैंने कोशिश की, इससे कोई समस्या नहीं आई, लेकिन यह हो सकता है।

यह भी ध्यान देने योग्य है कि line_is_def रेगेक्स शायद बहुत हल्का है। इस स्थिति में -1 वापस लौटना बेहतर हो सकता है, इसलिए रेगेक्स से मेल खाने वाली रेखा केवल तभी तब्दील हो जाती है जब यह फोल्ड विधि ब्लॉक के ठीक आगे हो। एक और अधिक प्रतिबंधक regex भी काम कर सकता है।

यदि आप गिलहरी महसूस कर रहे हैं, तो आप इस पर विस्तार कर सकते हैं और rubyClass और rubyModule तत्वों के लिए अलग-अलग फ़ोल्डवेल्स वापस कर सकते हैं।

यदि आप उस मार्ग पर जाने का फैसला करते हैं, तो कुछ useful custom functions in my .vimrc सिंटैक्स तत्वों और हाइलाइटिंग में आत्मनिरीक्षण के लिए हैं। वे handiest रहे जब इतनी तरह त्वरित उपयोग के लिए एक कुंजी बाइंडिंग को मैप किया: मुझे पता है अगर यह आपके लिए बाहर काम करता है

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

करते कृपया! यह पता लगाना मजेदार था।इसके अलावा, इसके लिए क्या मूल्य है, जबकि :help 'foldexpr' विवरण पर प्रकाश है, :help 'fold-expr' अधिक उपयोगी है, और यहां तक ​​कि शीर्ष पर कुछ उदाहरण भी हैं।

+2

यह एक अच्छा जवाब है। ऐसा लगता है कि यह सही समाधान है, या कम से कम एक महान प्रारंभिक बिंदु जहां मैं चाहता हूं। मैं यह देखने के लिए परीक्षण करूंगा कि यह आज के बाद कैसे काम करता है और आपका जवाब स्वीकार करता है। इसके अलावा आपका vimrc एक महान शिक्षण संसाधन की तरह दिखता है, खासकर आपके द्वारा परिभाषित सभी कार्यों के साथ। धन्यवाद। – adivasile

+0

आपका स्वागत है! मुबारक vimming! –

+0

मुझे यह जानने में दिलचस्पी होगी कि यह आपके लिए कैसे काम करता है! –

1

आप zO कमांड का उपयोग कर एक समाधान के साथ-साथ एक समाधान के साथ गुजरने में सक्षम हो सकते हैं। zO एक बार फिर से खोलने के लिए खोल देगा, इसलिए यदि आप zo के बजाय इसका उपयोग करते हैं, तो ऐसा होगा जैसे विधि के अंदर कुछ भी नहीं था। यदि आप गिलहरी महसूस कर रहे हैं तो आप zo को zO पर भी रीमेप कर सकते हैं।

+0

जो वास्तव में सहायक होगा, लेकिन मुख्य समस्या अभी भी बनी हुई है: विधियों को स्वचालित रूप से फोल्ड किया गया है। – adivasile

3

आप इस के साथ बेहतर किस्मत हो सकता है, खासकर अगर आप पहले से ही वाक्य रचना हाइलाइटिंग है: 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 है में जाना होगा

4

मैक्स कैंटोर के समाधान में बदलाव आया, मेरा काम पूरी तरह से काम करता है, यह डीफ़ विधियों (अंत कीवर्ड सहित) और दस्तावेज (= start = 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 जैसी लाइन है जो व्हाइटस्पेस या टैब से पहले है, तो यह हमेशा पहले गैर रिक्त वर्ण पर स्टैक प्राप्त करेगी। मैक्स कैंटोर के समाधान के साथ समस्या यह है कि उसका कोड केवल लाइन के पहले कॉलम पर पाए जाने वाले निम्नतम वाक्यविन्यास तत्व को मुद्रित करेगा, इसलिए यह हमेशा कुछ यादृच्छिक, "रूबीकंटेंट" जैसे तत्वों को वापस लाएगा जिनकी हमें परवाह नहीं है।

तो match(getline(a:line), '^\s*\zs') का उपयोग करके हम अपने कर्सर को पहले गैर रिक्त वर्ण के कॉलम पर ले जा सकते हैं ताकि हम ढेर की एक और सटीक तस्वीर प्राप्त कर सकें। +1 क्योंकि मिलान शून्य-अनुक्रमित है।

और फिर बाकी GetSynInfo विधि के समान है जहां हम ढेर के माध्यम से लूप करते हैं और हमारे इच्छित तत्वों से मेल खाते हैं, और 1 लौटाते हैं ताकि वे सभी एक ही गुना स्तर और बाकी के लिए 0 हो।

और बस हो गया, एक काम तह expr समारोह है कि केवल गुना होगा माणिक पद्धतियां निर्धारित :)

का आनंद लें और एक अच्छा दिन है!

+1

आपका उत्तर वादा करता है, लेकिन दुर्भाग्य से जब मैंने कोशिश की तो कुछ भी नहीं हुआ। ऐसा लगता है कि समाधान इन कार्यों को परिभाषित करने के लिए याद करता है: 'GetSynString' और' GetSynDict'। क्या आप उन्हें प्रदान करने की देखभाल करेंगे? धन्यवाद –

1

मैंने रूबी में सरल विधि फोल्डिंग के लिए vim-ruby-fold प्लगइन बनाया। मुझे उम्मीद है कि यह लोगों की मदद करेगा।