Vim में परिवर्तनशील नाम


96

मैं विम के माध्यम से बहुत सी / पर्ल कोड पढ़ने की कोशिश कर रहा हूं जिसमें कई एकल अक्षर चर नाम हैं।

कुछ कमांड रखना अच्छा होगा जो मुझे एक चर के नाम को कुछ और सार्थक बनाने में मदद कर सकता है जबकि मैं कोड पढ़ने की प्रक्रिया में हूं ताकि मैं इसे तेजी से पढ़ सकूं।

क्या विम में कुछ आज्ञा है जो मुझे जल्दी से ऐसा करने दे सकती है?

मुझे नहीं लगता कि regexes काम करेगा क्योंकि:

  1. एक ही अक्षर नाम के अलग-अलग स्कूपिंग ब्लॉक में अलग-अलग उद्देश्य हो सकते हैं

  2. अक्षरों का एक ही संयोजन एक और बड़े var नाम का हिस्सा हो सकता है, या एक स्ट्रिंग या टिप्पणी में ... उन को संशोधित नहीं करना चाहेगा

कोई ज्ञात समाधान?

जवाबों:


198

निम्नलिखित एक चर का नाम बदलने के लिए है जो वर्तमान दायरे में परिभाषित किया गया है {}

अपने कर्सर को परिवर्तनशील उपयोग में ले जाएँ। प्रेस करें gd। जिसका अर्थ है - कर्सर को परिभाषा में ले जाना। अब प्रेस [{- यह आपको गुंजाइश शुरू करने के लिए लाएगा। प्रेस V- विज़ुअल लाइन चयन चालू करेगा। प्रेस %- इसके विपरीत कूद जाएगा }इस प्रकार पूरे दायरे का चयन करेगा। प्रेस :s/- स्थानापन्न कमांड की शुरुआत। <C-R>/- वैरिएबल नाम (जो नाम आप प्रेस करने से पहले थे gd) से मेल खाते पैटर्न को सम्मिलित करेगा । /newname/gc<CR>- प्रत्येक मैच पर पुष्टि के साथ खोज और प्रतिस्थापन आरंभ करेगा।

अब आपको एक मैक्रो या इससे भी बेहतर रिकॉर्ड करना होगा - एक कुंजी को मैप करें।

यहाँ अंतिम मैपिंग हैं:

" For local replace
nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

" For global replace
nnoremap gR gD:%s/<C-R>///gc<left><left><left>

इसे अपने .vimrcया सिर्फ निष्पादित करें। इसके बाद grलोकल वेरिएबल पर प्रेस करने से आपको :sकमांड मिलेगी जहां आपको बस एंटर करना चाहिए new_variable_nameऔर प्रेस करना होगा Enter


40
5 से अधिक 5 नई विम ट्रिक्स सीखने के लिए, जो मुझे पहले पता होनी चाहिए। साभार
केनी मेयेर

6
नोट: gd मैकविम में जावास्क्रिप्ट मोड में परिभाषा के तत्काल दायरे में चर का पता लगाने के लिए काम नहीं करता है। यह फ़ाइल में किसी फ़ंक्शन में चर नाम का पहला उपयोग करने के लिए मुझे लेता है :( यदि आप कुछ दायरे में हैं और उस दायरे का चयन करना चाहते हैं, तो "va {" - "विज़ुअल सिलेक्शन {" - जाने का रास्ता है मुझे लगता है।
श्रीकुमार ३

3
थोड़ा उन्नत संस्करण: gist.github.com/048616a2e3f5d1b5a9ad उपयोगकर्ता को संकेत देता है, पुराना नाम दिखाता है, प्रतिस्थापित करने के बाद कर्सर की स्थिति को पुनर्स्थापित करता है
एंडी रे

7
+1 बहुत अच्छा विमिंजरिंग (मुझे लगता है कि मैंने सिर्फ एक नया शब्द गढ़ा है)। नोट: मुझे वास्तव में बृहदान्त्र ( :) को दो बार दबाने की आवश्यकता थी । पहली बार मैंने इसे दबाया, मैंने देखा :'<,'>। अगर मैं बस s/वहाँ से टाइप करता तो यह काम नहीं करता था; मुझे इससे पहले एक और कोलन टाइप करना था s/
केल्विन

6
ध्यान दें कि आपको <C-R>स्थानापन्न कमांड की आवश्यकता नहीं है , बस खोज को छोड़ने से अंतिम खोज पैटर्न का उपयोग करने का कारण होगा, जो इस मामले में gdकमांड से बनाया गया था । तो बस :s//<newname>/gcकरना पर्याप्त होगा।
१२ में shangxiao

10

AFAIK, VIM में कोई वास्तविक रीफैक्टरिंग समर्थन नहीं है। रिफ्लेक्टर के इरादे से नाम बदलने पर मैं आमतौर पर निम्नलिखित सावधानियां अपनाता हूं:

  1. मेरे उपयोग के निशान के परिवर्तन की सीमा को सीमित करें।
  2. रेगेक्स में प्रवेश करते समय, नाम को \ <और> के साथ ब्रैकेट करें। यह एक पूरे शब्द से मेल खाएगा जो गलत नाम बदलने के प्रकार को कम करेगा।
  3. एक बुरा जगह की संभावना को कम करने के लिए एक बहुपरत की जगह मत करो
  4. यदि यह एक छोटे से बदलाव के अलावा कुछ और है तो कोड के माध्यम से ध्यान से देखें।

मेरा अंत परिवर्तन कुछ इस तरह दिखता है

:'a,'bs/\<foo\>/bar

मुझे लगता है कि वीआईएम के लिए एक रीफैक्टरिंग टूल नहीं होने के बारे में गलत होगा, लेकिन मैंने इसे नहीं देखा।


पर्ल में आप सर्च पैटर्न में टाइप भी जोड़ सकते हैं। स्केलर के लिए $ $, सरणियों के लिए @, हैश के लिए%
नाथन फ़ेलमैन

@ नथन: दुर्भाग्य से, पर्ल (5.X) में यह थोड़ा अधिक कठिन है, क्योंकि सरणियों और हैश के सर्जन उपयोग के साथ बदलते हैं:% हैश -> पूरे हैश, $ हैश {कुंजी} -> एकल मूल्य, @sh { qw / ab /} हैश स्लाइस।
user55400

10

मुझे पता है कि यह एक पुराना प्रश्न है, और @ mykola-golubyev का रास्ता स्पष्ट रूप से ओपी प्रश्न में विशेष मामले के लिए सबसे अच्छा जवाब है (जो, मुझे लगता है कि आप मोटे कोड से गुजर रहे हैं जहां आपके कई अलग-अलग नाम होने की संभावना है) ; लेकिन इस सवाल के नाम के साथ कि Google खोजों से यहां आने वाले कई लोग शायद वीआईएम में चर नाम बदलने के लिए कम स्थिति-विशिष्ट तरीकों की तलाश करते हैं - और वे अधिक संक्षिप्त हो सकते हैं

मैं हैरान हूं कि किसी ने इस तरह से सुझाव नहीं दिया:

* :s// नया नाम /gc

यह *वैसा ही है gn- यह कर्सर के नीचे शब्द की अगली घटना को खोजता है और यह अंतिम खोजा गया पैटर्न बन जाता है, इसलिए जब आप विकल्प कमांड में खोज पैटर्न को छोड़ते हैं, तो VIM यह मान लेता है कि यह खोज करने के लिए पैटर्न है।

थोड़ी मात्रा में var प्रतियों के लिए, एक भी त्वरित:

* cw NEWNAME <esc> फिर n.अन्य घटनाओं के लिए दोहराता है

घटना की खोज, परिवर्तन शब्द केcw लिए कमांड है , अंतिम खोज शब्द की अगली घटना पर जाता है और अंतिम कमांड को दोहराता है (जो कि NEWNAME के ​​लिए शब्द बदल जाता है )n.

(मेरे लिए यह सब जानते हुए क्रेडिट @ Reddit पर @doomedbunnies पर जाएं )

एक और बढ़िया ट्रिक यह है: ( @ nobe4 को क्रेडिट )

* cgn NEWNAME <esc> फिर .अन्य घटनाओं के लिए दोहराता है

cgn"परिवर्तन जो भी हो (अगली घटना को ढूंढें)" है। अब जब यह अंतिम आदेश है , तो आपको nअगली घटना पर जाने की आवश्यकता नहीं है , इसलिए कम स्ट्रोक फिर से, और, अधिक महत्वपूर्ण बात, वैकल्पिक करने की आवश्यकता नहीं है nऔर .। लेकिन, जाहिर है, यह एक घटना को छोड़ने का तरीका नहीं होने का दोष है।

यहाँ कुछ लाभ दिए गए हैं:

  • कोई मैपिंग, नहीं .vimrc (या init.vim), इसलिए आप इसे किसी भी VIM कॉपी में उपयोग कर सकते हैं जो आपको आती है (उदाहरण के लिए कुछ VPS या आपके मित्र की मशीन पर त्वरित कार्य जहां VIM को कॉन्फ़िगर करना आपके 'त्वरित' के उद्देश्य को हरा देगा) )
  • शब्द चयन के लिए उपयोग करना *या gnजल्दी करना - बस एक कीस्ट्रोके (ठीक है, चलो 1.5 कहते हैं)
  • उपयोग *या gnसुनिश्चित करता है कि आपको अन्य शब्दों के अंदर कोई मेल नहीं मिलता है, जैसा कि :%s/<C-R>//gcकरता है। :%s/\<OLDNAME\>/NEWNAME/gcहाथों से टाइप करने वाले बीट्स : मैं व्यक्तिगत रूप से \<केवल शब्दों तक ही मैचों को सीमित करने के लिए चीजों का उपयोग करना भूल जाता हूं ।
  • स्कोप का उपयोग नहीं करने से केवल nअवांछित मैचों को छोड़ने के लिए कुछ अतिरिक्त स्ट्रोक होंगे - शायद गुंजाइश को सीमित करने के लिए आवश्यक अतिरिक्त स्ट्रोक से भी कम। सामान्य curcumstances के तहत, आपके चर कुछ हद तक एक निश्चित कोड ब्लॉक के लिए स्थानीयकृत हैं।

8

इसे अपने .vimrc में डालें

" Function to rename the variable under the cursor
function! Rnvar()
  let word_to_replace = expand("<cword>")
  let replacement = input("new name: ")
  execute '%s/\(\W\)' . word_to_replace . '\(\W\)/\1' . replacement . '\2/gc'
endfunction

इसके साथ बुलाओ :call Rnvar()

expand("<cword>")कर्सर के नीचे शब्द मिलता है। खोज स्ट्रिंग %फ़ाइल-स्कोप के लिए उपयोग करता है , और \(\W\)पैटर्न शब्द की सीमा पर गैर-शब्द वर्णों को बदलने के लिए देखते हैं, और उन्हें चर में सहेजते हैं \1और \2इसलिए प्रतिस्थापन पैटर्न में फिर से डाला जाता है।


3

आप वैश्विक खोज में 'c' संशोधक का उपयोग कर सकते हैं और प्रत्येक प्रतिस्थापन के लिए आपसे पुष्टि करने के लिए कहेंगे। इसमें अधिक समय लगेगा, लेकिन यह एक गैर-मानवीय कोड फ़ाइल के लिए काम कर सकता है:

%s/\$var/\$foo/gc

सी पुष्टि के लिए खड़ा है।


मैं नजरअंदाज मामले के लिए खड़ा है। आप सी चाहते हैं, हर बदलाव की पुष्टि करें।
माइकल क्रिस्टोफिक

उफ़ .. इसके बारे में क्षमा करें .. उत्तर तय किया
अदनान

उत्तर अभी भी पूरी तरह से तय नहीं है;)
user55400

क्या आपका मतलब $ बच गया? यह कुछ ऐसा है जो मेरा व्यक्तिगत पसंद है। $ बच के बिना काम करता है और रेगेक्स की दुनिया में और उसके बाद से $ vi का विशेष अर्थ है, मैं इसे स्पष्टता के लिए बचना पसंद करता हूं।
अदनान

0

C में, आप cscope का उपयोग करके कुछ प्रगति करने में सक्षम हो सकते हैं। यह वाक्य रचना को समझने का एक प्रयास करता है, इसलिए यह जानने का मौका होगा कि पत्र एक चर था।


0

यदि यह कई फाइलों में है, तो आप sed पर एक नज़र डालने पर विचार कर सकते हैं। एक जगह के लिए अपनी फ़ाइलों और xargs प्लस sed को पकड़ने के लिए खोज का उपयोग करें। कहते हैं कि आप सभी। * के साथ a_better_name से मिलान करना चाहते हैं। * .सी, आप कर सकते हैं

खोजो। -नाम "* .सी" | xargs sed -i -e 's / a / a_better_name / g'

इस बात को ध्यान में रखें कि यह सभी घटनाओं को बदल देगा, इसलिए आप अधिक मजबूत रेगेक्स चाहते हैं।

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