Vim'de değişken isimleri nasıl hızlı bir şekilde değiştirilir?


97

Birçok tek harfli değişken adı içeren çok sayıda C ve Perl kodunu okumak için Vim kullanıyorum.

Ben kodu okuma sürecindeyken bir değişkenin adını daha anlamlı bir şeye değiştirmek için bir komuta sahip olmak güzel olurdu, böylece geri kalanını daha hızlı okuyabilirim.

Vim'de bunu hızlıca yapmama izin verecek bir komut var mı?

Normal ifadelerin işe yarayacağını sanmıyorum çünkü:

  1. aynı tek harf adı, farklı kapsam bloklarında farklı amaçlara sahip olabilir; ve

  2. aynı harf bileşimi başka bir uzun değişken adının parçası, bir dize değişmezi veya bir yorum olabilir.

Bilinen herhangi bir çözüm var mı?

Yanıtlar:


202

Aşağıda, geçerli kapsamda tanımlanan bir değişkenin nasıl yeniden adlandırılacağı anlatılmaktadır {}.

İmlecinizi değişken kullanıma getirin. Tuşuna basın gd. Bunun anlamı - imleci tanıma taşımak. Şimdi Basın [{- bu sizi kapsamın başlangıcına getirecektir. - düğmesine Vbasmak Görsel Çizgi seçimini açacaktır. Tuşuna basın %- tersine atlayacak ve }böylece tüm kapsamı seçecektir. :s/Yedek komutun başlangıcına basın . <C-R>/- değişken adıyla eşleşen desen ekleyecektir (basmadan önce bulunduğunuz ad gd). /newname/gc<CR>- aramayı başlatacak ve her maçta onay ile değiştirecektir.

Şimdi bir makro kaydetmeniz veya daha da iyisi - bir anahtarı eşleştirmeniz gerekir.

İşte son eşlemeler:

" 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>

Bunu kendinize koyun .vimrcya da sadece çalıştırın. grYerel değişkene bundan sonra basmanız , :ssizi girip new_variable_namebasmanız gereken komuta getirecektir Enter.


40
Daha önce bilmem gereken 5'ten fazla yeni Vim numarası öğrenmek için +1. Teşekkürler
Kenny Meyer

6
Not: gd, macvim'de Javascript kipindeki tanımın hemen kapsamındaki değişkeni bulmak için çalışmaz. Değişken adının dosyadaki bazı işlevlerde ilk kullanımına götürür :( Belirli bir kapsam dahilindeyseniz ve bu kapsamı seçmek istiyorsanız, "va {" - "görsel seçim {" - gidilecek yoldur Sanırım.
Srikumar

3
Biraz iyileştirilmiş bir sürüm: gist.github.com/048616a2e3f5d1b5a9ad kullanıcıya sorar, eski adı gösterir, değiştirdikten sonra imleç konumunu geri yükler
Andy Ray

7
+1 çok iyi vimgineering (Sanırım yeni bir terim buldum). Not: Aslında :iki kez kolon ( ) tuşuna basmam gerekiyordu . İlk bastığımda gördüm :'<,'>. s/Oradan yazdıysam işe yaramadı; 'Den önce iki nokta üst üste yazmak zorunda kaldım s/.
Kelvin

7
<C-R>Yedek komutta ihtiyacınız olmadığını unutmayın , sadece aramayı atlamak vim'in bu durumda gdkomuttan oluşturulan son aranan kalıbı kullanmasına neden olur . Yani basitçe yapmak :s//<newname>/gcyeterli olacaktır.
shangxiao

15

Bunun eski bir soru olduğunu biliyorum ve @ mykola-golubyev'in yöntemi, OP sorusundaki belirli durum için en iyi cevaptır (ki, aynı değişken adlarına sahip birden çok bloğa sahip olabileceğiniz karmaşık kodlardan geçtiğini varsayıyorum) ; ancak, google aramalarından buraya gelen pek çok kişi, VIM'deki değişkenleri yeniden adlandırmak için daha az duruma özgü yollar arar ve bunlar daha kısa olabilir.

Kimsenin bu şekilde önermediğine şaşırdım:

* :s// YENİ İSİM /gc

*Aynıdır gno imlecin altındaki sözcüğün sonraki gerçekleşmesinde arar VE geçen deseni aranır hale siz yedek komuta arama deseni atladığınızda yüzden, VIM bu aramak için kalıptır varsayar -.

Küçük miktarlarda değişken kopya için daha da hızlı:

* cw NEWNAME, <esc> ardından n.diğer durumlar için tekrarlayın

Oluşum ara, cwiçin komut değişim sözcüğü , nson aranır vadeli bir sonraki geçtiği gider ve .(olan son komutu tekrarlar NEWNAME değişiklik kelime )

(Tüm bunları bilen krediler Reddit'te @doomedbunnies'e gidiyor )

Bir başka harika numara da şudur: ( @ nobe4 kredisi )

* cgn NEWNAME, <esc> ardından .diğer durumlar için tekrarlayın

cgn"(sonraki tekrarı bul) sonucunu değiştir" dir. Artık bu son komutn olduğuna göre, bir sonraki olaya gitmek için öğesine ihtiyacınız yok , bu nedenle tekrar daha az vuruş ve daha da önemlisi, değiştirmeye gerek yok nve .. Ancak, belli ki, bunun dezavantajı, bir olayı atlamanın bir yolunu bulamamaktır.

İşte bazı avantajlar:

  • eşleştirme yok, .vimrc (veya init.vim) yok, böylece karşılaştığınız herhangi bir VIM kopyasında kullanabilirsiniz (örneğin, VIM'i istediğiniz şekilde yapılandırmanın 'hızlı' amacını ortadan kaldıracağı bazı VPS veya arkadaşınızın makinesinde hızlı bir görev) )
  • kelime seçimi için *veya kullanmak gnçok hızlıdır - sadece bir tuş vuruşu (pekala, 1.5 diyelim)
  • kullanarak *veya gnbaşka kelimelerin içinde herhangi bir eşleşme olmadığından emin olmanızı sağlar :%s/<C-R>//gc. :%s/\<OLDNAME\>/NEWNAME/gcElle yazarak vuruşlar : Kişisel olarak, \<eşleşmeleri yalnızca tam kelimelerle sınırlamak için bazı şeyleri kullanmayı unutuyorum .
  • Kapsam kullanmamak, nistenmeyen eşleşmeleri atlamak için yalnızca birkaç ekstra vuruşla sonuçlanır - muhtemelen kapsamı sınırlamak için gereken ekstra vuruşlardan bile daha az. Normal koşullar altında, değişkenleriniz büyük olasılıkla bir şekilde belirli bir kod bloğuna yerelleştirilmiştir.

10

AFAIK, VIM'de gerçek bir yeniden düzenleme desteği yoktur. Bir refactor niyetiyle yeniden adlandırma yaparken genellikle aşağıdaki önlemleri alıyorum:

  1. İşaretlerimi kullanarak değişikliğin kapsamını sınırlayın.
  2. Normal ifadeyi girerken, adı \ <ve> ile parantez içine alın. Bu, ortaya çıkacak yanlış yeniden adlandırma türlerini azaltan bir kelimenin tamamını eşleştirmesini sağlar.
  3. Kötü bir değiştirme olasılığını azaltmak için çok satırlı bir değiştirme yapmayın
  4. Küçük bir değişiklikten başka bir şey varsa, kod farklılıklarına dikkatlice bakın.

Benim son değişikliğim böyle bir şeye benziyor

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

VIM için bir yeniden düzenleme aracı olmadığı konusunda yanılmak isterdim ama görmedim.


Perl'de türü arama modeline de ekleyebilirsiniz. yani skalarlar için $, diziler için, karmalar için%
Nathan Fellman

@Nathan: Maalesef, Perl (5.X) 'de biraz daha zor, çünkü dizilerin ve karmaların işareti:% hash -> tam hash, $ hash {key} -> single value, @hash { qw / ab /} karma dilimi.
user55400

9

Bunu .vimrc dosyanıza koyun

" 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

İle ara :call Rnvar()

expand("<cword>")imlecin altındaki kelimeyi alır. Arama dizgisi %dosya kapsamı için kullanır ve \(\W\)örüntüler, değiştirilecek sözcüğün sınırında sözcük olmayan karakterleri arar ve bunları değişkenlere kaydeder \1ve \2böylece değiştirme kalıbına yeniden eklenir.


3

Genel aramada 'c' değiştiricisini kullanabilir ve her değiştirme için sizden onay isteyecek olan yerine koyabilirsiniz. Daha uzun sürer, ancak çok büyük olmayan bir kod dosyası için çalışabilir:

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

C, onaylama anlamına gelir.


İ, görmezden gelme durumunun kısaltmasıdır. C istiyorsun, her değişikliği onayla.
Michael Kristofik

oops .. bunun için üzgünüm .. Cevap düzeltildi
Adnan

Cevap hala tam olarak düzeltilmedi;)
user55400

kaçan $ mı demek istediniz? Bu benim kişisel tercihim olan bir şey. $ kaçmadan çalışır ve ayrıca regex dünyasında ve vi $ 'da özel bir anlama sahip olduğundan, sadece açıklık için ondan kaçmayı seviyorum.
Adnan

0

C'de, cscope kullanarak biraz ilerleme kaydedebilirsiniz. Sözdizimini anlamaya çalışır, dolayısıyla harfin ne zaman değişken olduğunu bilme şansı olur.


0

Bu birden çok dosyada ise, sed'e bir göz atmayı düşünebilirsiniz. Dosyalarınızı ve xargs plus sed'i değiştirmek için bulmak için bul'u kullanın. * .C ile eşleşen tüm dosyalarda a'yı a_better_name ile değiştirmek istediğinizi varsayalım,

bul. -name "* .c" | xargs sed -i -e 's / a / a_better_name / g'

Bunun a'nın TÜM oluşumlarının yerini alacağını unutmayın, bu nedenle daha sağlam bir normal ifade isteyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.