तह-एक्‍सप्रैस कैसे लिखें?


10

मैंने सहायता पृष्ठ को फोल्ड-एक्सप्र ( :h fold-expr) के बारे में पढ़ा है लेकिन यह नहीं बताया कि अभिव्यक्ति में किस वाक्य-विन्यास का उपयोग किया गया है।

वहाँ चार उदाहरण थे:

  1. :set foldexpr=getline(v:lnum)[0]==\"\\t\"
  2. :set foldexpr=MyFoldLevel(v:lnum)
  3. :set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
  4. :set foldexpr=getline(v:lnum-1)=~'^\\s*$'&&getline(v:lnum)=~'\\S'?'>1':1

मैं समझ गया कि v:lnumवह लाइन है जिसे एक इंडक्शन स्तर की आवश्यकता है, और वह अभिव्यक्ति दो एक फ़ंक्शन के लिए एक कॉल है।

1,3 और 4 के भाव क्या हैं? क्या कोई मुझे उन्हें समझा सकता है?


मेरी समझ यह है कि अभिव्यक्ति को एक संख्या वापस करनी चाहिए, और उस संख्या का उपयोग यह निर्धारित करने के लिए किया जाएगा कि दी गई रेखा को किस स्तर पर मोड़ दिया जाएगा। 0 मुड़ा हुआ नहीं है, 1 सबसे बाहरी तह है, 2 एक तह 1 के स्तर के अंदर
घोंसला है

जवाबों:


12

से :help 'foldexpr':

प्रत्येक लाइन के लिए इसका गुना स्तर प्राप्त करने के लिए इसका मूल्यांकन किया जाता है

foldexprमूल्यांकन किया जाता है, तो यह VimL कोड की जरूरत है; "विशेष वाक्यविन्यास" या इस तरह का कोई उल्लेख नहीं है। इस मूल्यांकन का परिणाम यह नियंत्रित करता है कि विम किस तह को मानता है या नहीं।

संभावित मूल्य हैं

  0                     the line is not in a fold
  1, 2, ..              the line is in a fold with this level
  "<1", "<2", ..        a fold with this level ends at this line
  ">1", ">2", ..        a fold with this level starts at this line

यह वह जगह है नहीं पूरी सूची; आपके प्रश्न में केवल उदाहरणों में उपयोग किए गए हैं। :help foldexprपूरी सूची देखें


प्रथम

एक बार जब हम कुछ रिक्त स्थान जोड़ते हैं और एक :setकमांड में इस काम को करने की आवश्यकता होती है, तो पहले वाला काफी सरल होता है :

getline(v:lnum)[0] == "\t"
  1. getline(v:lnum) पूरी लाइन हो जाती है।
  2. [0] उस का पहला चरित्र हो जाता है
  3. और == "\t"जाँचता है कि क्या एक टैब वर्ण है।
  4. VimL में "सत्य" या "असत्य" नहीं है, यह सिर्फ "0" का उपयोग करता है, और "1" के लिए सच है। इसलिए यदि यह रेखा एक टैब से शुरू होती है, तो इसे फोल्डवेल 1 से जोड़ दिया जाता है। यदि ऐसा नहीं होता है, तो यह फोल्ड (0) में नहीं है।

यदि आप टैब की संख्या की गणना करने के लिए इसका विस्तार करेंगे तो आपके पास इंडेंटेशन-आधारित फोल्डिंग होगी (कम से कम, जब expandtabसक्षम नहीं है)।


तीसरा

तीसरा एक वास्तव में पहले वाले के रूप में अधिक जटिल नहीं है; पहले उदाहरण के साथ, हम पहले इसे और अधिक पठनीय बनाना चाहते हैं:

getline(v:lnum) =~ '^\s*$' && getline(v:lnum + 1) =~ '\S' ? '<1' : 1
  1. हमें पूरी लाइन मिलती है getline(v:lnum)
  2. हम साथ एक regexp रूप से मेल खाने वाले =~के लिए '^\s*$'; ^शुरुआत के लिए लंगर, \sकिसी भी व्हाट्सएप चरित्र का *मतलब है, पिछले शून्य या अधिक बार दोहराएं, और $अंत तक लंगर डाले। तो यह regexp रिक्त लाइनों या लाइनों के लिए केवल व्हाट्सएप से मेल खाता है ।
  3. getline(v:lnum + 1)अगली पंक्ति मिलती है ।
  4. हम इसके साथ मेल खाते हैं \S, जो इस लाइन पर कहीं भी किसी भी गैर-व्हाट्सएप चरित्र से मेल खाता है।
  5. यदि ये 2 स्थितियाँ सत्य हैं, तो हम इसका मूल्यांकन करते हैं <1, अन्यथा 1। यह ifसी और कुछ अन्य भाषाओं से ज्ञात "टर्नरी" के साथ किया जाता है condition ? return_if_true : return_if_false:।
  6. <1इसका मतलब है कि इस लाइन पर एक फोल्ड समाप्त होता है, और 1फोल्डवेल का मतलब है।

तो, अगर हम एक रेखा को समाप्त करते हैं यदि रेखा खाली है और अगली पंक्ति रिक्त नहीं है । अन्यथा, हम फोल्डवेल पर हैं 1. या, जैसा :h foldexprकि यह कहते हैं:

यह रिक्त लाइनों द्वारा अलग किए गए पैराग्राफ से एक गुना बना देगा


चौथा

चौथा तीसरे के समान ही व्यवहार करता है, लेकिन इसे थोड़ा अलग तरीके से करता है। विस्तारित, यह है:

getline(v:lnum - 1) =~ '^\s*$' && getline(v:lnum) =~ '\S' ? '>1' : 1

यदि पिछली पंक्ति एक रिक्त रेखा है, और वर्तमान रेखा एक गैर-रिक्त रेखा है, तो हम इस रेखा पर एक गुना शुरू करते हैं ( >1), यदि नहीं, तो हम 1 के लिए फेरलवेल सेट कर रहे हैं।


अंतभाषण

इसलिए सभी 3 उदाहरणों पर तर्क वास्तव में काफी सरल है। अधिकांश कठिनाई रिक्त स्थान की कमी और कुछ बैकस्लैश उपयोग में आती है।

मुझे संदेह है कि किसी फ़ंक्शन को कॉल करने का कुछ ओवरहेड है, और चूंकि इसका मूल्यांकन प्रत्येक पंक्ति के लिए किया जाता है जो आप एक अच्छा प्रदर्शन करना चाहते हैं। मैं नहीं जानता कि आधुनिक मशीनों पर कितना बड़ा अंतर है, और यह अनुशंसा करेगा कि आप एक फ़ंक्शन का उपयोग करें (जैसा कि 2 उदाहरण में) जब तक आप प्रदर्शन की समस्या नहीं करते हैं। द नूथ को याद रखें: "समयपूर्व अनुकूलन सभी बुराई की जड़ है"

यह सवाल स्टैकऑवरफ्लो पर भी है , जिसका जवाब थोड़ा अलग है। लेकिन मेरा पाठ्यक्रम बेहतर है ;-)


3

आप अनिवार्य रूप से पूछ रहे हैं कि इन अभिव्यक्तियों में अन्य तत्व क्या हैं, जिन्हें :helpबदले में उनमें से किसी के लिए कॉल करके पाया जा सकता है :

v:lnum: the line being evaluated
getline(): get the line of text for a line number
==: equals
=~: matches
<cond>?<if-true>:<if-false>: evaluates to <if-true> if <cond> is true, else to <if-false>

मैंने इन भावों को उनके अर्थों को समझने में मदद करने के लिए नीचे उनके भागों से तोड़ा है:

1 टैब के साथ शुरू होने वाली सभी लाइनों के लिए 1 और अन्य लाइनों के लिए 0 वापस आएगा:

v:lnum                      the current line number
getline(v:lnum)             the text of the current line
getline(v:lnum)[0]          the first character of the current line
getline(v:lnum)[0]==\"\\t\" the first char of the current line is 'tab'

पैराग्राफ के बाद रिक्त लाइनों पर 3 समाप्त होता है:

 getline(v:lnum)=~'^\\s*$'                                       current line is only spaces
                              getline(v:lnum+1)=~'\\S'           next line has non-space
(getline(v:lnum)=~'^\\s*$' && getline(v:lnum+1)=~'\\S') ? '<1'   if both of these: <1
                                                              :1 otherwise: 1
(getline(v:lnum)=~'^\\s*$' && getline(v:lnum+1)=~'\\S') ? '<1':1

पैराग्राफ शुरू करने वाली रिक्त लाइनों पर 4 सिलवटों को शुरू करता है:

(getline(v:lnum-1)=~'^\\s*$'                                     previous line only spaces
                                getline(v:lnum)=~'\\S'           this line has non-space
(getline(v:lnum-1)=~'^\\s*$' && getline(v:lnum)=~'\\S') ? '>1'   if both of these: >1
                                                              :1 otherwise: 1
(getline(v:lnum-1)=~'^\\s*$' && getline(v:lnum)=~'\\S') ? '>1':1 

के अर्थ <1, >1आदि में इन भाव नीचे सही कह रहे हैं:help fold-expr


1

गलती से मेरे जवाब को एक टिप्पणी के रूप में पोस्ट किया और इसे जल्दी प्रस्तुत किया। डारन मोबाइल।

मेरी समझ यह है कि अभिव्यक्ति को एक संख्या वापस करनी चाहिए, और उस संख्या का उपयोग यह निर्धारित करने के लिए किया जाएगा कि किस स्तर पर दी गई रेखा को मोड़ दिया जाएगा। 0 मुड़ा नहीं है, 1 सबसे बाहरी गुना है, 2 एक स्तर 1 गुना के अंदर एक नेस्टेड नेस्टेड है, और इसी तरह।

उदाहरणों में भाव ऐसे लगते हैं जैसे वे सही या गलत का मूल्यांकन करेंगे। VimScript में एक उचित बूलियन प्रकार नहीं है, इसलिए यह वास्तव में 1 या 0 होगा, जो कि वैध तह स्तर हैं।

आप VimScript का उपयोग करके अपनी अभिव्यक्ति लिख सकते हैं जो कि 1 या 0, या अधिक जटिल, नेस्टेड सिलवटों की अनुमति के रूप में सरल है।


सिर्फ संख्याओं का उपयोग करने से काम चल जाएगा, लेकिन यह ध्यान देने योग्य है कि फोल्डेक्प्रेट अन्य विशेष मूल्यों का मूल्यांकन कर सकता है, जैसे =, a1, s1,> 1, <1, -1
मैट बोएहम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.