Özgün sözcüğü yazmak zorunda kalmadan Vim'de nasıl bulunur ve değiştirilir?


53

Vim'deki "bul ve değiştir" iş akışımı optimize etmek istiyorum. Sık yaptığım bir şey, çoğunuzun da yaptığından emin olduğum gibi. Genellikle satırları boyunca bir şeyler - bir bloğu kopyalayın ve bir değişkenin adını birkaç yerde değiştirin. Biliyorum, biliyorum ki bu muhtemelen "kodunuzu neden kopyalayıp yapıştırıyorsunuz" refleksinizi tetikler, ancak bu yoldan aşağıya inmeyelim ... Çok sayıda geçerli kullanım durumu var :)

Arama ve değiştirme komutlarının farkındayım: :sya da :%sonlardan hoşlanmıyorum. Beni hem aradığım tam değişken adını hem de neye değiştirdiğimi yazmaya zorluyor. Belki yazarak miktarını düzeltmek için daha iyi bir yol var :%s? Sık sık uzun tanımlayıcı değişken isimleri kullanırım, bu yüzden bu benim için çok önemli. Ayrıca, sıfırdan değişken bir isim yazmanın yazım hatası eğilimi göstermesi ve zaman ve beyin gücünü yazım hataları içinde tüketebilmesinden hoşlanmıyorum. Bunu bir kez yazmayı ve sonra mümkünse bundan tamamen kaçınmak için kopyalayıp yapıştırmayı tercih ederim.

Mevcut iş akışım, dosya etrafında hareket etmek ve birer birer değiştirmek için / hareket / yank / select / search / put hareketinin bir kombinasyonunu kullanır. Harika değil ama tam değişken adlarını yazmaktan kaçınma avantajına sahiptir. Etrafınıza ne olduğuna bağlı olarak ilk birkaç harfi yazmam /veya başka bir hareket komutu (örn. fx) Kullanmam gerekebilir ve ardından vekelimenin tamamını seçmek için tuşuna basmam gerekebilir . Ayrıca her durum için tekrarlamam gerektiğini de umursamıyorum. Her değişikliği onaylamadan asla tam bir bulma işlemi yapmam. Ancak, değiştirme eylemini tek bir tuşa basarak (bu yöntemle yapamayacağım) tekrarlayabilsem daha çok tercih edilir. Her değiştirme genellikle no vezamanki gibi bir şeydir p(veya daha da kötüsü "0p)

Daha hızlı bir yolu var mı?


1
.son "komut bloğu" nı tekrar eder (örneğin, terimin tam olduğundan emin değildir. örneğin: örneğin: move + action + text. exemple: cwtoto<Esc>(imleçten kelimenin sonuna "toto" ile c/foo<enter>bar<Esc>değiştir ), foo "ve" bar "ile değiştir). sonra hareket edebilirsin (imleç, hjkl veya sayı + hjkl ile (n kere yapar), G (dosyanın sonuna git), / bir şey (hemen önce git) bir şey "), vb) ve sonra .aynı" komut bloğunu "yinelemek için basın
Olivier Dulac

Bunu biraz kullanırım! Bununla birlikte, bir kelimeyi yanklamak ve daha sonra başka bir kelimeyi birden fazla yerde değiştirmek istiyorsanız bu işe yaramaz. Bu benim problemim olan ana kullanım durumu ve buna benzer bir şey n ve "0p. Maalesef sadece birlikte taklit edilemeyen Hangi.
Joel

5
n ce ctrl-r 0 <esc> n.n.n.n.n.n.
Zengin

@Joel ayrıca bir makro da kaydedebilirsiniz (qa sonra istediğiniz her şeyi, sonra q: makro a oluşturur) ve sonra şunu kullanın: @a tekrar yapmak için (ve her zamanki gibi 134 @ a 134 kez yapın). Makro, gerektiği kadar ayrıntılı olabilir (örnek: bir şey bulun, uygun yere gidin, sonra kelimeyi değiştirin, sonra daha iyi bir konumda tekrar aranabilmek için uygun yere gidin)
Olivier Dulac

1
Bu sorudan sitedeki diğer herhangi bir sorudan daha faydalı VIM püf noktaları öğrendim. Teşekkür ederim!
dotancohen

Yanıtlar:


81

Aslında sizinkine oldukça benzer bir iş akışına sahibim (benzer blokları kopyalayıp yapıştırarak, sonra :sdeğişken isimlerini değiştirmek için kullanıyorum ), özellikle de kullandıkları değişken dışında benzer birçok satır yazarken. Fakat yararlı bulabileceğiniz birkaç şey var.

Genel vim şeyler

  1. Size yardımcı olacak ilk şey, :s//foo/gen son kullandığınız arama terimini dolduracağının ve bunu foo ile değiştireceğinizin farkına varmaktır . Bu tek başına çok fazla zaman kazandırabilir, ancak onu yıldız işareti komutuyla birleştirdiğinizde (geçerli imlecin altındaki sözcüğü arayın) tonlarca zaman kazanır. Örneğin, yapmak yerine, hepsini değiştirmek fooiçinspam

    :%s/foo/spam/g
    

    Hem foo hem de spam (uzun değişkenler olabilir) yazmanızı gerektirir, foo'ya gidebilir ve şunları yapabilirsiniz:

    *:%s//spam/g
    

    Bu şekilde, değiştirerek değişkenin adını hızlı bir şekilde bulabilir, sonra da yazmaya gerek kalmaz. Bu aynı zamanda mevcut iş akışınızla nçok iyi çalışacaktır . Ayrıca, faydalı olması gerekir hlsearch, çünkü görsel olarak değiştirdiğiniz değişkenlerin nerede olduğunu görsel olarak anlayabilirsiniz.

    (yan not: kelime sınırlarını katacak yıldız komutu, yani \<ve \>imlecin altındaki kelime etrafında bunu istemiyorsanız kullanın. g*Bunun yerine.)

  2. Değiştirme işlemini tek bir tuşa basarak tekrarlayabilirsem çok daha iyi olurdu.

    @:Son değiştirme komutunu tekrarlamak için kullanabilirsiniz . :sÇok sayıda satıra komut vermek istiyorsanız , ancak hepsi :%sişe yaramazsa bu çok hoş . Başka bir seçenek de onaylama bayrağı, yani :%s///gc. Bu, değiştirmek isteyip istemediğinize karar vermek için her bir durumda yazmanıza yveya yazmanıza olanak sağlar n.

    As destY işaret , ayrıca yapabilirsiniz &geçen yedek komutunu yeniden çalıştırın, ancak bu unutmamaları değil Bayraklarınızı (örneğin tutmak globalya confirm). Bunun iyi ya da kötü olması kişisel görüşünüze bağlıdır. Bunu kullanmak istersen fakat bayraklarını da elinde tutmasını istiyorsan, yapabilirsin.

    nnoremap & :&&<cr>
    
  3. Bir bloktaki her oluşumu değiştirmek istiyorsanız, ancak dosyadaki her eşleşmeyi değiştirmek istemiyorsanız, her zaman doldurulacak bloğun görsel bir seçimini kullanabilirsiniz.

    :'<,'>
    

    Seçeceğiniz satırlarla sınırlayan alternatifinize Yıldız yaklaşımı ile birlikte, bu son derece yararlı buluyorum. Ayrıca, aynı satır bloğunda birden çok yedek komut gvyapıyorsanız, başka bir komut yapmak için aynı satırları yeniden seçmek için kullanabilirsiniz . (ister :substitutenormal isterse komut)

    Başka bir yedek komutunu yaparsanız, yok gerek , çünkü aynı satırları yeniden seçmek için :'<,'> hala aynı hatlarda çalışacaktır. Ancak, yazmak daha uygundur.

    gv:s
    

    ziyade

    :'<,'>s
    

Beğendiğim Eklentiler / Eşlemeler

  1. Yıldız işaretleme yaklaşımını.vimrc genişleten benim içimde aşağıdaki eşleştirmeler var, böylece sadece istenen yeni ismi yazmam gerekiyor:

    "(R)eplace all
    nnoremap <leader>r yiw:%s/\<<C-r>"\>//g<left><left>
    

    Bunu kullanmak için imleci değiştirmek istediğiniz kelimenin üzerine getirin ve yazın <leader>rNewVarName<cr>ve bitirdiniz. Bunun, size onaylama seçeneği vermeden tüm eşleşmelerin yerine geçeceğini, bu nedenle beğenmeyeceğinizi unutmayın. Tabii ki, sadece değiştirebilirsiniz

    nnoremap <leader>r yiw:%s/\<<C-r>"\>//gc<left><left><left>
    

    Onay seçeneğine izin vermek için.

    düzenlemek : Her iki takiben Mass cevabı ve rcorre yorumuna , ayrıca bu yazabiliriz

    nnoremap <leader>r :%s/\<<C-r><C-w>\>//g<left><left>
    

    Adsız sicilinizi aynı tutma avantajına sahiptir.

  2. Aynı anda benzer değişken gruplarını yeniden adlandırıyorsanız, örneğin

    fooSuffix
    PrefixFoo
    foo1
    SHOUTINGFOO
    

    için

    barSuffix
    PrefixBar
    bar1
    SHOUTINGBAR
    

    hepsini ayrı ayrı ikame etmek acı verici olabilir. Burası tpope / vim-abolish'in kullanışlı olduğu yerdir . Bunların hepsini tek bir komutla değiştirebilirsiniz:

    :%S/foo/bar/g
    

    ve sizin için büyük harf kullanımı ile ilgilenir.

Bunlar size çok yardımcı olmalı, ancak bu yaklaşımlarla ilgili beğenmediğiniz veya eksik hissettiğiniz bir şey varsa bana bildirin. Daha fazla yaklaşım hakkında konuşmaktan mutluyum. :)


Önerilen Kaynaklar:


Oh, burada birkaç şey öğrendim. Güzel! Alabileceğiniz alternatif bir yaklaşım <leader>rc(veya cr) /csonuna eklemek . Ayrıca, set gdefaultbelirledim, çünkü neredeyse hiç bir zaman tek bir sonucun yerini almak istemiyorum, bu yüzden olur yiw:%s/\<<C-r>"\>//<left><left>
Wayne Werner

2
Ne harika bir cevap!
Scott Lundberg

2
Eğer ctrl+r-ctrl+wharitalamada (@Mass tarafından önerildiği gibi) kullanırsanız, aynı şekilde çalışması gerekir ancak yank sicilinizi karıştırmaz (ki bu arzu edilebilir veya istenmeyebilir)
rcorre

1
Vurguladığınız metin blokları ile çalışırken hatırlamanız gereken bir şey (kesim / çentikleme vb. Öncesi) en son vurgulu metni yeniden vurgulamak için normal modda gv girebilmenizdir.

1
Yöntem 2'ye benzer çalışan github.com/hauleth/sad.vim eklentisini yazdım . Hoewewer, .başka değiştirmeler yapmak için kullanmanıza izin veriyor .
Hauleth,

20

c_CTRL-RHaritaların aile iş akışınızı biraz iyileştirebilir:

  1. Kullanırken değişken isimleri girmenize gerek yoktur :s/, sadece CTRL-R CTRL-Wimlecin altındaki kelimeyi komut satırına eklemek için kullanın (uyarı: bu, özel karakterler gibi *, kaçmaz).

  2. Kullanarak küçük bir değişiklik yaptıktan sonra ce, eski kelimeyi kullanarak arama yapabilirsiniz / CTRL-R -. Ardından .değişikliği tekrarlamak için kullanın .

  3. Arama modelinde değişiklik yapmanız gerekirse CTRL-R /, mevcut aramayı komut satırına yerleştirir.

  4. Sonunda, kullanarak herhangi bir sicil içeriğini koyabilirsiniz CTRL-R {register}


İyi bir nokta! Her zaman Ctrl R'yi unutuyorum. Bunu da başarabilir miyim, göreceğim.
Joel

2
Özellikle bahsetmeye değer Ctrl-R /mi? :sHemen hemen öncekilerle tamamen aynı olmayan bir arama terimi kullanmak istersem bunu komutlarda çok sık kullanıyorum.
Zengin

12

(Sürprizime!) Henüz söylenmemiş birkaç yöntem daha var.

gnKomutu Kullanma

gnnKomuta benzer şekilde çalışır , ancak maça atlamanın yanı sıra, seçilen tüm eşleme ile görsel moda girer.

Bir sözcüğü değiştirmek (veya normal ifadeyle eşleştirebileceğiniz herhangi bir şeyi!) Değiştirmek için önce onu arayın 1 , ardından cgneşleşmeyi değiştirmek ve Escnormal moda dönmek için ardından metne basın.

(Bazen kullanmak istediğiniz yedek metnin "0yank kayıt defterinde saklandığından bahsedersiniz Ctrl+R0- ekleme modundayken yeniden yazmak zorunda kalmadan hızlıca girebileceğinizi unutmayın .)

Sonra bir sonraki maça geçebilir ve değişikliği tek bir .tuşa basarak tekrarlayabilirsiniz !

Eğer herhangi bir yerde varsa yok değiştirilmesini yapmak istiyorum, sadece basın undeğişikliği geri ve bir sonraki maç atlamak için.

1: pençelere seri gibi bu sayfadaki diğer önerileri kullanarak *, Ctrl+RCtrl+Wvb Ayrıca bkz Peter Rincker yorumuna başlangıçta aramanızı doldurmak konusunda daha fazla öneriler için.

Seçme Modunu Kullanma

(Ben ögrendik romainl 'ın vim subreddit üzerine yazı . Onun bunun kendisi icat ya da sadece geçen olup olmadığını bilmiyorum.)

Seçim modu, biraz önce görsel mod gibidir; seçili metni hemen yazdıklarınızla değiştirirseniz (seçimin diğer çoğu düzenleyicide nasıl çalıştığı gibi) hemen değiştirilir.

Böylece, bu eşleme üçlüsünü, gerektiğinde ortadaki dosyayı değiştirebileceğiniz çok hızlı bir bulma / değiştirme işlemi yapmak için kullanabilirsiniz:

nnoremap § *``gn<C-g>
inoremap § <C-o>gn<C-g>
snoremap <expr> . @.

Normal mod eşlemesi : Seçilen imlece en yakın olan kelime ile seçme moduna girer.

Daha sonra (seçilen sözcük için Değişim amaçlı yazıp edebilir olmadan basarak Esckullanın):

Mod eşleştirme ekle : Bir sonraki eşleşmeye atlar ve seçim moduna girer.

Daha sonra yeni bir değiştirme yazabilir veya .aşağıdakileri kullanmak için tuşuna basabilirsiniz :

Mod eşleştirme seç : Son eklenen metni tekrar girer - esasen son ekleme işlemini tekrar eder.


gnCevabımın sonunda vi.stackexchange.com/a/13696/488 cevabımın sonundaki yöntemden bahsettim ! Yanıtınız çok daha güzel biçimlendirmeye sahip.
TankorSmash 27:17

1
@TankorSmash Yani yaptın! Bunu nasıl özlediğime dikkat et. Kullandığım asıl yöntemin sizinkinden farklı olduğunu, ancak (yalnızca bir gnkez çağırdım ) ve gnşaşkın olduğumun henüz belirtilmemiş olan belirli bir yöntem (sadece komut yerine ) olduğunu unutmayın.
Zengin

Ben sahip öneriyoruz çeşit ait "görsel yıldız" ile kullanmak eklenti gn. Size daha fazla arama seçeneği sunar. Kötü adamın görsel yıldız haritalama: xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>. İlgili Vimcasts bölüm: aramada Çalışma gn kullanarak maçları
Peter Rincker

1
Ben böyle bir akış ile yardımcı eklenti sad.vim oluşturduk .
Hauleth

7

Eklenti https://github.com/terryma/vim-multiple-cursors , çoğunlukla bu sorunu önemser.

İş akışım genellikle şöyledir:

  1. İmleci değiştirilecek sözcüğe getirin.
  2. ctrl-nHer şey seçilene kadar basılı tutun .
  3. Tuşuna basın cve değiştirmeyi yazmaya başlayın.

Buradaki en uygun şey, arama-değiştirme işleminden daha karmaşık işlemler yapabilmenizdir, ancak bunu çok ileri götürürseniz, eklentinin bazı aksaklıklar göstermeye başladığını fark ettim.


4

Henüz belirtilmeyen şeyleri yapmanın başka bir yolu: Vim'in otomatik tamamlama özelliklerine ( / ve çeşitli dizilere) tam erişime sahip olduğunuz komut satırı penceresini ( q:normal modda açılmış - :help q:daha fazla bilgi için bkz .) Kullanabilirsiniz. onların arasında olmak).i_CTRL-Ni_CTRL-Pi_CTRL-X

Komut satırı penceresinde, komut satırını düzenlemek için normal mod komutlarını da kullanabilirsiniz; bu, örneğin, önceki komutların parçalarını komut satırı geçmişinize kopyalayıp yapıştırabileceğiniz anlamına gelir.

İmlecinizi, kullanırken komut satırı penceresine taşınacağını, yani CTRL-R CTRL-Wimlecin altına metin eklemeyi içeren benzer yöntemlerin normal komut satırındakilerin aksine orada çalışmadığını unutmayın.


1
Komut satırı penceresini zaten yarıya kadar girdikten sonra :substitutekomutunuza girerken<ctrl-f>
Zengin

2

Bunun çözümü benim için diğer cevaplar arasında biraz:

6 aynı çizginiz olduğunu ve ortadaki 'elmayı' değiştirmek istediğinizi varsayalım:

I have apples for days
I have apples for days
I have apples for days
I have apples for days
I have apples for days
I have apples for days

Yaptığım şey:

  1. 'Elma' yerine değiştirmek istediğim metnin başına geliyorum
  2. Hit vgörsel moduna almak için
  3. Değiştirmek istediğim son sözcüğe gidin, bu durumda birkaç satır 2j
  4. :s/<C-R><C-W>/görsel seçimi için aralık olarak kullanır :sve sonra imlecin altına bir sözcük ekler.
  5. Seni <C-F>, komutunu tampon gibi düzenleyebileceğin bir moda sokana çarptım. Böylece değiştirme kelimesini seçmek istediğiniz tamamlamayı veya eklentiyi kullanabilirsiniz, tamamdır.

Hepsi bir satırda, bunun için akış olacaktır, /apples<CR>2nv/apples<CR>nn:s/<C-R><C-W/oranges<CR>ancak ondan daha kötü görünüyor.

Durumunuzda, aralığınızda atlamak istediğiniz birkaç tane varsa, istemediklerinizi atlamak /ciçin :skomutu ekleyebilirsiniz :s/<C-R><C-W/orange/c.

Alternatif (ve belki de daha basit), size değiştirmek istediğiniz tüm kelime için arama olabilir c, sonra hange onu gnve .aramanızı tekrar tekrar aynı değişikliği uygulamak için. Bunu /\<apple\><CR>viwcorange<ESC>gn.gn.gn..ngn.üçte tekrarlamak, sonra bir örneği atlamak, sonra son bir kez tekrarlamak gibi görünüyor.


Sonunda tarif ettiğiniz yöntem benim için işe yaramıyor (Vim 7.4'te, ile çağrıldı vim -Nu NONE). İlkine bastığımda sadece bip sesi geliyor .. Bunun neden olduğu hakkında bir fikrin var mı? Her durumda, kullanımı kolay olurdu ciwyerine viwve nyerine gnbu şekilde değişiklik yapmak için.
Zengin

2

Bu tamamen soru ile ilgili değildir, ancak yine de değiştirilecek sözcüğü seçmeye yardımcı olmalıdır.

Artımlı arama ( set incsearch), bulmanız gereken kelimenin ön ekini yazmanıza olanak tanır ve vim daha fazla yazarken otomatik olarak ön ekin ilk oluşumuna atlayacaktır. Enter tuşuna basarsanız ve Esc'ye atılırsanız arama onaylanır (ikinci durumda imleç, arama başlamadan önceki yerine geri döner).

Ancak, artımlı arama, bir daha kullanışlı özellik sağlar. Önceden bir kelimenin ön ekini yazdığınızda ve imleç doğru pozisyondayken, <C-L>imlecin altındaki kelimeden arama dizisine karakter eklemek için tuşuna basın . Bu, değiştirilen dizeye neredeyse hiç tuşa basmadan girmenizi sağlar.

Yani, değiştirmek istiyorsanız someOddVariableNameile evenOdderVariableNameben

  1. yazın /someOddVve gelmesi someOddVariableName;
  2. arama satırında tamamen görünene <C-L>kadar basılı tutun someOddVariableName;
  3. aramayı onaylamak için Enter tuşuna basın;
  4. :%s//evenOdderVariableName/gveya ihtiyacınız olan komutu değiştirmek için; Burada diğer cevapları takip etmek isteyebilirsiniz.

2

Değişken adını önce ywbir kelimeyi ( bir kelimeyi kopyalamak için) tampon belleğe koyabilir , sonra üstüne :%sbasarak kopyalayıp yapıştırabilirsiniz <C-r>".


2

Yeni (yapıştırılan) blok içindeki bir değişkeni değiştirmek istiyorsanız iki önerim var:

Otomatik değiştirme

  • Yeni bloğun ilk satırına git, vur ma. Bu bir yeri işaretliyor ve isimlendiriyor a.

  • Yeni bloğun son satırına git, vur mb. Şimdi iki adlandırılmış konumunuz var.

  • Şimdi iki satır arasında değiştirin :'a,'bs/oldVarName/newVarName/g.

  • Yani, ikame kapsamı iki işaretiniz arasındadır.

Manuel yol

  • Yeni bloğun ilk satırına gidin.

  • /oldVarNameİlk örneğini bulmak için kullanın oldVarName.

  • Öyle değiştirin:, cwnewVarName<Esc>kelimeyi değiştirecek newVarNameve kaçışa vuracak .

  • nSonraki örneğine gitmek için kullanın oldVarName.

  • .Son değişikliği tekrarlamak için kullanın (yani bunu tekrarlar cw).


2

Buradaki diğer cevapların çoğu, bul ve değiştir iş akışını iyileştirmenin yerleşik yollarını zaten kapsıyor ancak Tim Pope'un bir eklentisi olan abolish.vim'den bahsetmek istedim . Normalde durumdaki değişikliklerin neden olduğu veya bir kelimenin hem tekil hem de çoğul halleriyle uğraşmanız gerektiğinden, daha geniş bir vaka yelpazesini kapsayacağınız yerlerin yerini alır.

:S/child{,ren}/adult{,s}/gdoğru dönüştürür childiçin adult, Childreniçin Adultsve CHILDetmek ADULT.

Eğer deve harfli kelimelerle uğraşıyorsanız, orijinal ve değiştirilen kelimelere ihtiyaç duyduğunuz harfleri eklemeniz gerekir.

%:S/wordWrap/textBreak/gher ikisini de doğru şekilde kullanır wordWrapve wordwrap.


0

Diğerlerinin de belirttiği gibi, imlecinizi kelimenizin üstüne getirdiyseniz, Ctrl + r komut ailesini kullanabilirsiniz, Ctrl + r Ctrl + w, muhtemelen en uygun olanıdır.

Bununla birlikte, bu yöntem yalnızca bir kelimeyi (imlecin hemen altındaki olanı) eklemek için işe yarar, ancak arabellekte kullanmak istediğimiz birkaç metin bölümü varsa ne olur? Yapamadığınız gibi imlecinizi komut satırında hareket ettirin. Bunu yapmanın en iyi yolu, "{reg_letter} (alıntı ve sicilden yazılan mektuplar") kopyalayan operatöre önek ekleyerek yapabileceğiniz metin bölümlerini farklı kayıtlara kopyalamaktır. daha sonra Ctrl + r {reg_letter} ile komut satırına çeşitli kelimeler ekleyin.Bu biraz garip ama işe yarıyor.

Fakat önceki fikre geri dönersek, bir desen yazarken imleç pozisyonunu tampon üzerinde hareket ettirirsek harika olurdu. Bu yolla, metni Ctrl + r Ctrl + w ile farklı konumlardan " seçebildik " , bu yüzden sadece şunu yapan bir eklenti oluşturdum: EXtend.vim

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.