त्वरित खोज, C ++ फ़ंक्शन तक सीमित है


13

मैं एक बड़े C ++ प्रोजेक्ट पर काम करता हूं। इसके संगठन के अधिक निराशाजनक पहलुओं में से एक बहुत बड़े कार्यों को हास्यास्पद रूप से बड़ी फ़ाइलों के अंदर रखा गया है।

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

(मैं ctags स्थापित है और Tagbar का उपयोग करें ... जो इस के लिए उपयोगी हो सकता है)

जवाबों:


9

यहां बताया गया है कि मैं यह कैसे करूंगा। इसे अपने में जोड़ें.vimrc

vnoremap if [[O][

स्पष्टीकरण: vnoremap का अर्थ है दृश्य मोड में रहने के दौरान बाएं हाथ की ओर ifदाईं ओर का नक्शा [[mO][ifमतलब फंक्शन में , यदि आप चाहें तो इसका नाम बदल सकते हैं। [[फ़ंक्शन की शुरुआत में कूदता है। Oआपके नेत्रहीन चयनित पाठ के दूसरे छोर पर ][जाता है , और फिर फ़ंक्शन के अंत में जाता है।

इसलिए, यदि आप किसी फ़ंक्शन में खोज करना चाहते हैं, तो अब आप दृश्य मोड में प्रवेश करते हैं v, और पूरे फ़ंक्शन का चयन करते हैं if। अब दृश्य मोड से बाहर निकलें <esc>, और साथ खोजें /\%V\%Vपहले से चयनित पाठ में आपकी खोज को प्रतिबंधित करता है। यदि आप हिट नहीं करना चाहते हैं तो <esc>/\%Vआप इसे अपने साथ जोड़ सकते हैं .vimrc:

vnoremap / <esc>/\%V

तब, कीस्ट्रोक्स का आपका क्रम ऐसा दिखेगा:

vif/foo<enter>

और यह मौजूदा फ़ंक्शन में फू की सभी घटनाओं को ढूंढेगा।


इस पद्धति का एकमात्र नकारात्मक पहलू यह है कि यह दोनों को 0 इंडेंटेशन खोलने और बंद करने की उम्मीद करता है। यदि आप नियमित रूप से उस कोड के साथ काम करते हैं जिसमें यह नहीं है, जैसे

int foo() {
    bar()
}

तब यह थोड़ा और अधिक जटिल संस्करण काम करेगा:

vnoremap if ][ma%O'a

यह केवल समापन ब्रेस से 0 इंडेंटेशन की उम्मीद करता है। यदि उद्घाटन ब्रेस में इंडेंट्स हैं, तो यह अभी भी काम करता है, हालांकि यह एक निशान लेता है। यदि आप नियमित रूप से मार्क 'ए' का उपयोग करते हैं, तो आप इसे उदाहरण के लिए स्थानांतरित कर सकते हैं

vnoremap if ][mb%O'b
vnoremap if ][mc%O'c
...

काश यह सी + + कार्यों के साथ अच्छी तरह से काम नहीं करता है। सी फ़ंक्शंस के विपरीत, वे इंडेंट होने की संभावना रखते हैं (यह इनलाइन सदस्यों के कार्यों के साथ उनकी कक्षा परिभाषा में परिभाषित है, और नेमस्पेस के भीतर फ़ंक्शन के डिफ़ॉल्ट इंडेंटेशन के साथ)। हालाँकि आपके विचार को फंक्शन डेफिनिशन रेंज के लिए धन्यवाद के आधार पर बनाया जा सकता है जिसे ctags के साथ प्राप्त किया जा सकता है। मैं इसे lh#dev#find_function_boundarieslh-dev
ल्यूक हर्मिट्टे

3
अच्छा तरीका। यदि आप फ़ंक्शन की शीर्ष पंक्ति को मज़बूती से पा सकते हैं, तो आप नीचे स्थानांतरित करने के लिए {उपयोग %कर सकते हैं। निश्चित नहीं है कि आप C ++ में फ़ंक्शन कैसे शुरू कर सकते हैं, लेकिन यह जावास्क्रिप्ट के लिए ठीक काम करता है:vnoremap if <Esc>?^\s*function<CR>v/{<CR>%o
joeytwiddle

1
आपके पिछले संपादन के बारे में। CTRL-]कर्सर के नीचे टैग पर कूदता है। वर्तमान फ़ंक्शन की शुरुआत के लिए नहीं। यह मदद नहीं करेगा।
ल्यूक हरमिट

नए संपादन के बारे में। यह इतना आसान नहीं है। कठिनाई को मौजूदा फ़ंक्शन को जानना है। यदि इसकी जानकारी होती, तो इसे ctags मदद की आवश्यकता नहीं होती। सूचना प्राप्त करने का एकमात्र तरीका (ctags से) ctags द्वारा निर्मित जम्प-टू-डिक्लेरेशन कमांड का विश्लेषण करना है । यदि ये कमांड थे :linenumber, तो मैं अपने प्लगइन में क्या कर सकता हूं। लेकिन इसकी कोई गारंटी नहीं है, और ये कमांड्स बजाय खोज के हो सकते हैं /pattern- विम सभी पैटर्न को यह जानने के लिए परीक्षण नहीं कर सकता है कि कौन सा फ़ंक्शन वर्तमान फ़ंक्शन से मेल खाता है। वाह, मुझे वर्तमान की शुरुआत में कूदने के लिए किसी भी विम कार्रवाई के बारे में पता नहीं है समारोह
ल्यूक हरमिट

6

डीजे मैकमेमे के समाधान ने मुझे अपनी खुद की लिखने के लिए प्रेरित किया जो कार्य सचिवों पर निर्भर करता है और कार्य सचिवों का एक उचित विश्लेषण करने के लिए मेल खाता है।

कठिन भाग पहले ही कई वर्षों के लिए lh-dev और lh-tags द्वारा किया जा चुका है :

  • वर्तमान फ़ाइल को सही विकल्पों के साथ ctags के माध्यम से पार्स किया गया है
  • हम टैग डेटाबेस में सभी फ़ंक्शन परिभाषाओं की तलाश करते हैं जो वर्तमान फ़ाइल के लिए प्राप्त टैग्स तक ही सीमित है
  • DB के लिए धन्यवाद, हमारे पास सभी कार्यों के लिए स्टार्ट लाइन नंबर हैं (अच्छी तरह से templateऔर inlineभाग ctags द्वारा याद किया जा सकता है)
  • एक साधारण पुनरावृत्त खोज के साथ (एक बाइनरी खोज की जा सकती थी, लेकिन अच्छी तरह से, फ़ाइलों को "संक्षिप्त" माना जाता है), वर्तमान फ़ंक्शन की शुरुआत पाई जाती है
  • और मिलान प्लगइन के लिए धन्यवाद, इसकी अंतिम पंक्ति के रूप में अच्छी तरह से पाया जाता है - मैं देखता हूं कि सार्वभौमिक ctags एक ऐसा endक्षेत्र प्रदान कर रहा है जिसका उपयोग C, C ++, Python और Vim के साथ किया जा सकता है जिसका उपयोग किसी फ़ंक्शन के अंत को खोजने के लिए भी किया जा सकता है।

ध्यान दें कि इस एल्गोरिथ्म के किसी भी हिस्से को फ़ाइल-प्रकार के आधार पर ओवरराइड किया जा सकता है। अर्थात् अजगर कार्यों की सीमाओं का पता लगाने defऔर इंडेंटेशन का विश्लेषण करने के लिए , हम सिर्फ functionजावास्क्रिप्ट में खोज सकते हैं , और इसी तरह - दूसरे शब्दों में, वर्तमान संस्करण जावा, विम और कुछ अन्य भाषाओं के साथ भी काम करता है (मुझे अभी भी कुछ काम है) पायथन के लिए)

इसलिए मैं अब दो नए मैपिंग परिभाषित करता हूं: एक दृश्य मोड मैपिंग, और एक ऑपरेटर-लंबित मोड मैपिंग:

onoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr>
xnoremap <silent> if :<c-u>call lh#dev#_select_current_function()<cr><esc>gv

जो पर भरोसा करते हैं:

function! lh#dev#_select_current_function() abort
  let fn = lh#dev#find_function_boundaries(line('.'))
  exe fn.lines[0]
  normal! v
  exe fn.lines[1]
endfunction

मैंने आपको कोड की कई सौ पंक्तियों को छोड़ दिया है lh#dev#find_function_boundaries()

और डीजे मैकमैहेम के मानचित्रण के लिए धन्यवाद

" Note that my vim settings requires two backslashes here instead of one
vnoremap / <esc>/\\%V

हम वर्तमान फ़ंक्शन के vif/patternलिए खोज कर सकते हैं pattern

हम इसके साथ फ़ंक्शंस को डिलीट भी कर सकते हैं dif, उन्हें साथ yifमें इत्यादि कर सकते हैं ।

जब यथार्थवादी C ++ फ़ंक्शन पर लागू किया जाता है तो यह ऐसा दिखता है (यानी 0 इंडेंट नहीं):Screencast: C ++ फ़ंक्शन का चयन करें


4

किसी फ़ंक्शन की शुरुआत और अंत का पता लगाना मुश्किल हो सकता है, विशेष रूप से एक functionकीवर्ड के बिना एक भाषा में ... और कई परस्पर विरोधी इंडेंट स्टाइल।

यदि आपका कार्य अपनी स्वयं की लाइन पर एक बंद ब्रेस के साथ समाप्त होता है (जैसा कि यहां सूचीबद्ध 13 शैलियों में से 10 में है ), तो आप नेत्रहीन इसे कुछ इस तरह से चुन सकते हैं:

xnoremap if /^\s*}<CR><Esc>V%

वहाँ से, fooअपने फंक्शन के लिए खोज करना केवल एक मामला है:

:'<,'>g/foo/#

यह सब एक साथ रखकर, हम एक अच्छी मैपिंग प्राप्त कर सकते हैं:

xnoremap if /^\s*}<CR><Esc>V%
nmap <key> vif:g//#<Left><Left>

फ़ंक्शन में खोजें

उस ने कहा, दृश्य मोड मानचित्रण शायद आसानी से whileया ifतो एक मूर्ख बनाया जाएगा तो यह शायद थोड़ा चमकाने से लाभ होगा। इसके अलावा, दृश्य चयन एक बहुत अच्छा विचार नहीं हो सकता है ...


यह सिर्फ अगले ब्लॉक का चयन करता है जो इसे पा सकता है। यह सब पर काम नहीं करता है एक बार आप जोड़ना if, for, while, आदि
जेम्स

3

एक अपूर्ण समाधान सिलवटों का उपयोग कर रहा है । सब कुछ मोड़ो:

set foldmethod=syntax
set foldlevel=0
set foldminlines=0

खोज परिणामों के लिए मुड़े हुए क्षेत्रों को न खोलने के लिए विम को बताएं:

set foldopen-=search

और फिर प्रश्न में फ़ंक्शन पर गुना खोलें ( zO)।

अब, एक तह क्षेत्र में खोजे गए पाठ के लिए सभी हिट्स के परिणामस्वरूप विम को एक बार गुना लाइन पर कूदना होगा, फिर अगली हिट के लिए आगे बढ़ना होगा।

उदाहरण के लिए, नीचे के मामले में:

यहाँ छवि विवरण दर्ज करें

फोल्ड किए गए फ़ंक्शन के कई उपयोग हैं size, लेकिन nमुझे sizeउस फ़ंक्शन के प्रत्येक उपयोग के आसपास नहीं ले जाएगा ।


3

दूसरा रास्ता:

  • लक्ष्य फ़ंक्शन को खोजने के लिए ctags आदि का उपयोग करें, वहां जाएं
  • फ़ंक्शन बॉडी के अंदर कर्सर ले जाएं
  • केवल वर्तमान ब्लॉक के भीतर खोज करने के लिए ओशियो मंगा के खोज ऑपरेटर ( विम-ऑपरेटर-उपयोगकर्ता पर निर्भर करता है ) का उपयोग करें। उदाहरण के लिए:

    " configure the plugin (once, vimrc):
     map g/ <Plug>(operator-search)
    
    " 1. use ctags etc. to jump to the beginning of the target function;
    " 2. move cursor inside the function definition, then:
    g/i{
    

... अब आप दिए गए संकेत पर अपना खोज शब्द सम्मिलित कर सकते हैं; हिट nदेखने के लिए कैसे खोज परिणामों वर्तमान प्रदान की गति / पाठ-वस्तु तक सीमित हैं। चूँकि यह एक विम (यानी कंपोज़ेबल) ऑपरेटर है, यदि आपके पास एक अच्छा फंक्शन टेक्स्ट-ऑब्जेक्ट है, तो आपको सर्च करने से पहले डेफिनिशन बॉडी के अंदर जाने की भी ज़रूरत नहीं है, लेकिन सीधे जैसे g/if, या इसी तरह की स्मेलिंग का इस्तेमाल करते हैं ।

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