कुछ वाक्य रचना क्षेत्रों में पैटर्न की खोज कैसे करें?


10

मैं लेटेक्स दस्तावेजों को संपादित करने के लिए विम का उपयोग कर रहा हूं। अक्सर, मैं एक चर का नाम बदलकर कुछ और करना चाहूंगा। हालाँकि, जब मैं चर नाम की खोज करता हूं, तो अप्रासंगिक मैचों से गुजरना थोड़ा कष्टप्रद होता है। मैं केवल "गणित क्षेत्रों" में खोज करना चाहता हूं क्योंकि टेक्स सिंटैक्स फ़ाइल में परिभाषित किया गया है। क्या किसी विशिष्ट सिंटैक्स क्षेत्र में खोज को सीमित करने का एक आसान तरीका है?


1
मुझे लगता है कि उत्तर नहीं है: किसी विशिष्ट सिंटैक्स क्षेत्र में खोज को सीमित करने का कोई आसान तरीका नहीं है।
कार्ल यंगवे लेर्वाग

2
यह मानचित्रणsynIDattr() कर्सर के नीचे वर्ण के लिए सिंटैक्स समूह प्राप्त करने के लिए उपयोग करता है। आप एक फ़ंक्शन लिख सकते हैं जो खोज करता है (या करता है normal n) और फिर synIDattr()यह तय करने के लिए उपयोग करता है कि क्या इस स्थान पर रहना है, या आगे की खोज जारी रखना है।
joeytwiddle

@joeytwiddle मैंने ऐसे समारोह के साथ एक उत्तर पोस्ट करने के बाद अभी आपकी टिप्पणी देखी। क्या आपके मन में ऐसा था?
jadaderberg

@jjaderberg हाँ यह है। अच्छा काम!
joeytwiddle 14

बस पूर्णता के लिए (मुझे यह एक अच्छा उत्तर मिला): stackoverflow.com/a/2696143/5000478
VanLaser

जवाबों:


4

यहाँ एक फ़ंक्शन है जिसे आप आज़मा सकते हैं। मैंने केवल इसका थोड़ा परीक्षण किया है, लेकिन यह ठीक काम करता है।

function! JJSyntaxSearch(pattern, syntaxitem)
  while search(a:pattern, 'W') > 0
    for id in synstack(line("."),col("."))
      if synIDattr(id,"name") =~? a:syntaxitem
        return line(".")
      endif
    endfor
  endwhile
  return 0
endfunc

command! -nargs=* JJSyntaxSearch call JJSyntaxSearch(<f-args>)

फ़ंक्शन एक लूप में विम के खोज फ़ंक्शन को तब तक कॉल करता है जब तक कि वह एक 'साधारण' मैच नहीं पाता है जो किसी विशेष वाक्यविन्यास आइटम के लिए 'योग्य' मैच है, या जब तक कि यह बफर के अंत तक नहीं पहुंचता है।

यह दो तर्क लेता है। पहला सर्च पैटर्न है और इसे विम के search()फंक्शन में अपरिवर्तित रखा गया है । देखें :help search()कि यह कैसे काम करता है। दूसरा तर्क सिंटैक्स आइटम का नाम है जिस पर आप इन मैचों को फ़िल्टर करना चाहते हैं। यह एक पैटर्न भी हो सकता है और इसकी तुलना केस-असंवेदनशील नियमित अभिव्यक्ति के रूप में की जाती है।

गणित क्षेत्रों में पैटर्न 'अल्फा' को खोजने के लिए आप कर सकते हैं

:JJSyntaxSearch alpha texMathZone.

.अंत में किसी भी एक वर्ण के लिए पैटर्न परमाणु है, देखते हैं :help /.। ऐसा इसलिए है क्योंकि वहाँ कई गणित क्षेत्र वाक्यविन्यास आइटम कहा जाता है texMathZoneA, texMathZoneBआदि।

search()समारोह अगले 'साधारण' मैच के लिए कर्सर ले जाता है। तब हमारे फ़ंक्शन को उस नए कर्सर स्थिति के लिए सभी सिंटैक्स आइटम आईडी मिलते हैं synstack()। उनके माध्यम से लूपिंग, यह बदले में प्रत्येक आइटम का नाम पुनर्प्राप्त करता है और syntaxitemतर्क के खिलाफ परीक्षण करता है। देखें :help synstack()और :help synIDattr()। यदि कोई 'योग्य' मैच है तो वह लाइन नंबर देता है। यदि यह बिना किसी 'योग्य' मिलान के बफर के अंत तक पहुँचता है, तो यह रिटर्न करता है 0। फ़ंक्शन का बिंदु कर्सर को अगले 'योग्य' मैच के लिए प्राप्त करना है ताकि आप वहां कुछ ऑपरेशन कर सकें, लेकिन यह इंगित करने के लिए "लाइन नंबर या 0" वापस करना उपयोगी है कि क्या फ़ंक्शन को फिर से कॉल करना सार्थक है, के लिए उदाहरण यदि आप फ़ंक्शन को किसी अन्य फ़ंक्शन या मैक्रो से बार-बार कॉल करना चाहते हैं।

मैंने Wध्वज का उपयोग करने के लिए चुना search()क्योंकि यह बफर के अंत में 'लपेटने' को रोकता है। अन्यथा फ़ंक्शन अटक सकता है क्योंकि यह समान 'साधारण' मैचों को ढूंढता रहता है लेकिन कोई 'योग्य' मैच नहीं।


आपकी सहायताके लिए धन्यवाद! मैंने अभी तक इस फ़ंक्शन की कोशिश नहीं की है, लेकिन यह वैसा ही दिखता है जैसा मैं चाहता था।
रोब एफ।


1

यदि आपका "गणित क्षेत्र" कुछ वाक्य रचना पैटर्न द्वारा योग्य है, तो कहें, स्ट्रिंग "गणित", तो आप कम से कम पैटर्न अनुक्रमों का उपयोग मिलान पैटर्न के साथ एक लाइन खोजने के लिए कर सकते हैं, जैसे कि:

:/math//your pattern/

(नोट: दो पैटर्न अलग-अलग लाइनों पर हो सकते हैं!)

यह आपके मैचों को क्षेत्र तक सीमित नहीं कर सकता है - इसके लिए आपको क्षेत्र के अंत की पहचान करने की आवश्यकता होगी - लेकिन यह प्रारंभिक पैटर्न / गणित / के बाद केवल उन मैचों को प्रदर्शित करेगा। आप पूर्व-मोड इतिहास ( : up-arrow enter) का उपयोग करके अगली घटना की खोज दोहरा सकते हैं ।


नोट: ISTR कि पहले के vim / vi संस्करणों में मैं /math//your pattern/कम टाइपिंग nऔर Nकमांड के उपयोग के लाभ के साथ एक खोज कमांड के रूप में उस विधि का उपयोग सीधे (एक पूर्व-मोड कमांड के विपरीत) करने में सक्षम था , लेकिन मैं पुष्टि नहीं कर सकता मेरे वर्तमान विम संस्करण के लिए।


1

यदि आप स्ट्रिंग को fooअंदर खोज रहे हैं $...$या $$...$$, यह काम करना चाहिए:

\$.*\zsfoo

यह मैच को एक $चरित्र के रूप में जोड़ता है लेकिन केवल स्ट्रिंग का चयन करता है foo

यह वास्तव में एक आसान समाधान नहीं है, लेकिन "गणित क्षेत्रों" को खोजने और उनके अंदर खोज करने के लिए एक :global+ :substituteका उपयोग कर सकता है:

:global /\v\\begin\{%(align|alignat|displaymath)\}/ +1,/\\end/-1 s/foo/&/gc

:substituteएक खोज आदेश है, यह दिखाते हुए कि आप अगली घटना के साथ जा सकते हैं nऔर साथ छोड़ सकते हैं q। क्या आपको गलती से प्रतिस्थापन की पुष्टि करनी चाहिए कोई समस्या नहीं होनी चाहिए।

आपको सूची को अंदर सेट करना होगा %(... )आपके द्वारा उपयोग किए जाने वाले गणित वातावरण के नामों के लिए (पूरी सूची थोड़ी भारी है:) align|alignat|displaymath|eqnarray|equation|flalign|gather|math|multline|subequations|xalignat|xxalignat। ध्यान दें कि मैं \vयहां बहुत ही जादू ( ) पैटर्न का उपयोग कर रहा हूं ।

स्पष्टीकरण:

:globalएक पूर्व आदेश (निष्पादित :sप्रत्येक पंक्ति पर) जहां पैटर्न मैचों ( :help :global)
/\vएक बहुत ही जादू पैटर्न शुरू ( :h /, :h pattern, :h magic)
\\begin\{एक शाब्दिक से मेल \begin{
%(align|alignat|displaymath)मैच दों में से कोई ( :h /\%(, :h /bar)
\}/एक शाब्दिक से मेल खाते हैं }और पैटर्न खत्म।

+1,/\\end/-1एक पंक्ति जिसमें अगली पंक्ति होती है (खोज से मिली हुई गणना :global) जो खोज पैटर्न द्वारा पाई गई रेखा से पहले होती है /\\end। उस सीमा के भीतर,

s/foo/&/gcfooपुष्टि के बाद, शाब्दिक की प्रत्येक घटना को स्वयं के साथ खोजना और बदलना ( :h :substitute)


यह निश्चित रूप से एक शुरुआत है, लेकिन मैं समीकरण, संरेखित और IEEEeqnarray वातावरण का लगातार उपयोग करता हूं, और मैं उन लोगों को अपनी खोज से बाहर नहीं करना चाहता।
रोब एफ।

@RobF: वातावरण की एक सीमा के भीतर मिलान करना काफी संभव है, लेकिन जब तक कोई इसे स्क्रिप्ट नहीं करता, यह आसान नहीं होगा। यदि, हालांकि, आप लगातार \mathitचर नामों का उपयोग करते हैं, तो उन्हें ढूंढना बहुत आसान है।
पीटर लुईरिन

0

यदि आप स्ट्रिंग 'सुबह' फ़ाइल के अंदर लिए हैं खोज /morningतो enterऔर प्रेस nआगे की दिशा स्थानांतरित करने के लिए


1
प्रश्न में कहा गया है कि I would like to search only in "math zones"आपका तरीका पूरी फाइल को खोजता है जो शोध क्षेत्र का परिसीमन नहीं करता है।
statox

0

इसके लिए एक समर्पित फ़ंक्शन लिखने के अलावा कोई विकल्प नहीं है। मैंने एक फ़ंक्शन लिखा है जो आपके द्वारा वांछित स्ट्रिंग को खोजता है और केवल तभी रुकता है:

  1. यह मैचों से बाहर चलाता है
  2. एक मैच है जो गणित के माहौल के अंदर है (यह मैच पर रोक होगा)

आप इसे केवल उस स्ट्रिंग के साथ कहते हैं जिसे आप खोजना चाहते हैं।

function! Finmath(nextstr)
    while 1
        if search(a:nextstr)==0
            break
        endif
        if searchpairpos('\(', '','\)','n')!=[0,0]
            break
        endif
        if searchpairpos('\[', '','\]','n')!=[0,0]
            break
        endif
        let a = getcurpos() 
        if count(strpart(getline('.'),0,a[2]),'$')%2==1
            break
        endif 
    endwhile 
endfunction

मैं GrammerousCheck के लिए एक समान फ़ंक्शन लिखने का इरादा रखता हूं जो केवल गणित के बाहर व्याकरण की त्रुटियों पर रुकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.