Vim'de kayıt defterine metin koymadan silmenin bir yolu var mı?


470

Vim kullanarak sık sık kod bloğunu yeni çektiğim bir blokla değiştirmek istiyorum.

Ancak değiştirilecek kod bloğunu sildiğimde, o bloğun kendisi, sadece çektiğim bloğu silen kayıt defterine gider. Bu yüzden istemediğimi silerek, sonra ekleyerek, sonra silerek alışkanlığım var, ama büyük kod blokları ile bu eklenen blok ve blok ayrı silmek için tutmak için dağınık olur.

Peki Vim'deki metni değiştirmenin en hızlı ve en hızlı yolu nedir?

  • kayıt olmadan metni silmenin bir yolu var mı?
  • "bir sonraki kelimeyi değiştir" veya "bir sonraki paragrafa kadar değiştir" demenin bir yolu var mı?
  • veya bir şekilde çoklu kayıt özelliğini kullanmanın en iyi yolu mu?

1
vim-easyclip ( github.com/svermeulen/vim-easyclip ) bu sorunun üstesinden gelmek için tasarlanmıştır
Steve Vermeulen

1
Bilmeden (o sırada) asıl probleminizin kopyasını bilmeden bir soru sordum , ancak başlık sorununun çok değil. TL; DR - kullandığınız ile değiştirin viwp( word için).
OJFord

Yanıtlar:


430

Bir şeyi kayıt defterine kaydetmeden silmek için "kara delik kaydı" nı kullanabilirsiniz:

"_d

Tabii ki ilginizi çekmeyen diğer kayıtlardan herhangi birini de kullanabilirsiniz.


4
İlk başta bu komutun düzgün çalışmadığını düşündüm. Sonra Amerikan klavyesinin "ölü tuşlar" versiyonunu kullandığımı fark ettim. Bu klavye düzeni ile yazmak zorundayım "<space>_d. ""
Yazmak

4
Bunu sadece boş satırlarda seçici olarak yapmaya dair bir fikrin var mı? ( ddBoş bir çizgide olursam , kara deliğe girer, aksi takdirde ddnormaldir).
Jonathan Dumaine

6
Bir karakteri kaldırmak için şunu deneyin:"_x
kenorb

54
Bu, standart bir metin düzenleyicinin kazandığı bir alandır. Sil tuşuna basmanız yeterlidir.
Vince Panuccio

22
Ayrıca yy'3yy' (ya da her ne olursa olsun) ile adsız kayıtta, ancak 0'da da bir şey çekebilirsiniz. Daha sonra "0pkullanılmasına rağmen, yapıştırabilirsiniz d.
Halfgaar

102

Evet. Önce "eski" metni silmekten biraz daha kıvrımlıdır, ancak:

İle başlıyorum ..

line1
line2
line3
line4

old1
old2
old3
old4

Ben shift+ vSatırı 1, satır 2, 3 ve 4 seçin ve bunları silmek dkomutu

Sonra eski 1-4 satırlarını aynı şekilde silerim.

Sonra,

"2p

Bu ikinci son sıralanmış çizgileri (1-4. Satır) yapıştırır. "3psondan üçüncüyü yapacak vb.

Bu yüzden sonunda

line1
line2
line3
line4

Referans: Numaralı kayıttaki Vim belgeleri


Eğer <Shift-v> ile satır seçerseniz, onları dd ile değil, sadece d ile
silmiş olursunuz

31
1 ila 9 silme işlemleri için çalışır. . Son şey yapıştırmak için gerçekten Yani başka bir şey ilk değiştirme amacı şey verilirse durumlarda yararlıdır siz "0p kullanmak zorunda ( 'y' ile) çekti, ama sonra başka bir şey varsayılan macunu kayıt üzerine yazar.
Rafael de F. Ferreira

Daha fazla karmaşıklığı geri almak için Gundo (grafiksel geri alma) komut dosyasına göz atın .
Lumi

@ RafaeldeF.Ferreira: Yorumunuz bu soruya bir cevap değil, ama aslında OP'yi ilk etapta soruyu sormaya yönlendiren gerçek problemi çözüyor. Benim için asıl sorun buydu.
0xc0de

76

VIM belgeleri: Numaralı kayıt 0, komut ["x] ile başka bir kayıt belirtmedikçe, en son yank komutundaki metni içerir.

Örneğin biz "foo" yank ve "bar" silmek - kayıt defteri 0 hala "foo" içerir! Bu nedenle "foo" kullanılarak yapıştırılabilir"0p


53

Geçerli seçimi arabellekle değiştirmenize olanak tanıyan kolay bir haritaya sahip olmak kullanışlı.

Örneğin, bunu .vimrc'nize koyduğunuzda

vmap r "_dP       // it's a capital 'p' on the end

daha sonra, bir şeyi kayıt defterine kopyaladıktan sonra (yani 'y' ile), sadece değiştirmek istediğiniz metni seçebilir ve sadece klavyenizdeki 'r' tuşuna basabilirsiniz. Seçim mevcut kaydınızla değiştirilecektir.

Açıklama:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste

1
Daha gelişmiş bir sürüm için şunları kontrol edin: stackoverflow.com/questions/290465/…
Luc Hermitte

vmap <C-P> "_dP
Harry Lee

7
Metni, seçimi silmeden koyabilirsiniz. Örneğin Vp, şu anki satırınızı hemen yanmış olanla değiştirir.
Bobby Marinoff

Bu çözüm, dgenellikle silme işlemi için kullanılmakta olan sorunu çözmez.
Victor Yarema

35

Vimrc'ime aşağıdakileri koydum:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Şimdi pano kaydına çekildim ve koydum ve varsayılan kayıtta ne olduğu umurumda değil. Ek bir avantaj, en az güçlükle diğer uygulamalardan yapıştırabilmemdir. Bazı işlevleri kaybediyorum, biliyorum, ama yine de birden fazla kayıt / pano izleyemiyorum.


6
Tüm bu yeniden eşlemeler yerine, set clipboard=unnamedveya set clipboard=unnamedplusvarsayılan panoya sırasıyla *veya değerini değiştiren veya yapabilirsiniz +.
Steve

5
@Steve Bunu yaparsanız, o zaman d panoya kayıt için son yank üzerine yazacaktır, bu da sorunun kaçınmaya çalıştığı şeydir.
79E09796

1
@ 79E09796, bunun olacağını ima etmek istemedim; Orijinal soruya değil, bu cevaba yorum yapıyordum.
Steve

1
Bunları .vimrc'ime koydum ve şimdi soran işe yaramıyor. Neden olduğu hakkında bir fikrin var mı?
tba

2
@tba noremap'i nnoremap (iki n) ile değiştirir ve iyi çalışır.
Meain

24

Verdiğiniz belirli örnek için, soruyu anlarsam bu işe yarayabilir:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)

6
Bu, birden çok seçime yapıştırmak istediğiniz durumlar dışında iyi sonuç verir.

23

Tüm yank ve delete işlemleri varsayılan olarak adsız kayıt defterine yazılır. Ancak, en son çekilme ve en son silme her zaman numaralandırılmış kayıtlarda (ayrı olarak) saklanır. Kayıt 0en son çekildi. Kayıtlar 1-9en son 9 silme işlemini (1 en son olmak üzere).

Başka bir deyişle, bir silme, adlandırılmamış kayıttaki en son yank üzerine yazar, ancak hala 0kayıtta bulunur. Karadelik kayıt hilesi ("_ddDiğer cevaplarda belirtilen ), adsız kaydın üzerine yazılmasını engellediği için çalışır, ancak gerekli değildir.

Bir kayıt çift tırnak kullanarak başvuru, böylece en son çekilir metin yapıştırmak şöyle yapılabilir:

"0p

Bu mükemmel bir referans:


16

EBGreen'in söylediklerini vurgulamak için :

Metin seçerken yapıştırırsanız, seçilen metin yapıştırılan metinle değiştirilir .

Bazı metinleri kopyalayıp birden çok konuma yapıştırmak istiyorsanız, yapıştırmak için kullanın "0p. Numaralı kayıt 0, en son yank komutundaki metni içerir.


Ayrıca, tüm kayıtlarınızın içeriğini listeleyebilirsiniz:

:registers

Bu komut, dbr'nin cevabı gibi bir şey yaparken hangi kaydı istediğinizi bulmanızı kolaylaştırır . Ayrıca, /,%, # kayıtlarını göreceksiniz. (Ayrıca bakınız :help registers)


Ve son olarak, kontrol edin cWve cWbir boşluk içeren ve içermeyen bir kelimeyi değiştirmek için. (Büyük Wharf kullanımı noktalama işaretlerini içerir.)


10

Vim kullanıyorsanız, o zaman seçmek gibi görsel moda sahip olacaksınız, ancak vi / vim'in temelini oluşturan ayırma modları ile.

Yapmak istediğiniz şey kaynağı seçmek için görsel modu kullanmak, sonra çekip, hedefin kapsamını seçmek için tekrar görsel modu kullanmak ve sonra varsayılan arabellekten metne yapıştırmaktır.

Misal:

İle bir metin dosyasında:

1 | qwer
2 | asdf
3 | zxcv
4 | poiu

şu sırayla: ggVjyGVkpile biteceksiniz:

1 | qwer
2 | asdf
3 | qewr
4 | asdf

Açıklaması:

  • gg: ilk satıra git
  • V: görsel modu tüm satırlarla başlat
  • j: bir satır aşağı git (seçim önceki satırlarda başlayarak seçimi bir satır aşağı büyütür)
  • y: varsayılan arabelleğe yönlendirilir (seçilen iki çizgi ve otomatik olarak görsel moddan çıkar)
  • G: son satıra git
  • V: görsel modu başlat (öncekiyle aynı)
  • k: bir satır yukarı git (daha önce olduğu gibi, görsel mod etkinken seçimi bir satır yukarı çıkar)
  • p: yapıştır (son iki satırdaki seçim ile, bu satırları arabellekte ne varsa değiştirir - bu durumda ilk 2 satır)

Bu, son bloğu arabelleğe koyan biraz rahatsız edici, bu nedenle aynı şeyin tekrarlanan yapıştırmaları için bir şekilde istenmiyor, bu nedenle kaynağı "ay("a adlı bir arabelleğe) ") ekleyin ve benzer bir şeyle yapıştırın "ap(ancak sonra programlama yapıyorsanız, muhtemelen birkaç kez yapıştırmak istemezsiniz, ancak bir işlev oluşturmak ve çağırmak değil, değil mi? SAĞ ?).

Sadece vi kullanıyorsanız, o zaman görsel mod yerine görünmez işaretleri kullanmak zorundasınız, bunun hakkında :he markdaha fazla bilgi için üzgünüm, ancak bu görünmez işaretlerle çok iyi değilim, görsel mod ile oldukça kontamine oldum.



9

Tembel olanlar için minimal invaziv bir çözüm:

Kayıt 0her zaman son yank içerir ( Rafael , alex2k8 ve idbrii daha önce de belirtildiği gibi). Ne yazık ki 0her zaman kayıt seçmek oldukça sinir bozucu olabilir, bu yüzden varsayılan olarak pkullanırsa iyi olurdu "0. Bu, aşağıdaki satırları bilgisayarınıza koyarak elde edilebilir .vimrc:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

İlk satır her pkonturu eşleştirir "0p. Ancak bu, pdiğer kayıtlara erişilmesini önler . Bu nedenle p, açıkça seçilmiş bir kaydı olan tüm konturlar for-loop içindeki eşdeğer komut satırı ifadesine eşlenir. Aynı şey için de yapılır P.

Bu yolla, şimdi kayıt kullanan örtük pve Pkonturlar dışında standart davranış korunur0 varsayılan olarak .

İpucu 1: Kesme komutu artık "0dsadece yerine d. Ama tembel olduğum için bu benim için çok uzun;) Bu nedenle aşağıdaki eşlemeyi kullanıyorum:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

Lider tuşu \varsayılan olarak, böylece \dveya yazarak metni kolayca kesebilirsiniz \D.

İpucu 2: Çok tuşlu eşlemeler için varsayılan zaman aşımı süresi oldukça kısadır. Bir kayıt seçerken bu süreyi uzatmak isteyebilirsiniz. Ayrıntılar :help timeoutleniçin bakın, kullanıyorum:

set timeout timeoutlen=3000 ttimeoutlen=100

7

İlk önce şu komutu yapın:

:h d

Ardından, belirli bir kayıt defterine silebileceğinizi fark edeceksiniz. Bu şekilde varsayılan kaydınızdakileri değiştirmezsiniz.


1
["x]d{motion} Delete text that {motion} moves over [into register x]- Vim:h d
Wes Turner

5

Benim durumum: Normalmodda, xtuşa basarak karakterleri sildiğimde , bu silme işlemleri en son kaydımın üzerine yazılıyor - en son kaydımdaki karakterleri kullanarak karakterleri silmek xve yapıştırmak istediğim karmaşık düzenlemeler (örneğin aynı metni ikiye yapıştırarak veya daha fazla yer).

Kabul edilen cevapta ( "_d) öneriyi denedim , ancak işe yaramadı.

Ancak, /vi/122/performing-certain-operations-without-clearing-register adresindeki kabul edilen cevap / yorumlardan , bunu benim için ekledim ~/.vimrc, işe yarıyor (Vim'i yeniden başlatmanız gerekebilir) ):

nnoremap x "_x

Yani, artık normal yank ( y), delete ( d) ve paste ( p) komutlarımı yapabilirim - ve sildiğim karakterler xartık en son kayıtları doldurmaz.


4

Metin ekleme, ekleme modundayken varsayılan kayda gitmez.


2
ancak varsayılan modda önemli miktarda metni silmek YAVAŞ
Hamish Downer

3

Doğru bağlamlarda kullandığım iki çözüm;

  • Vims VISUALmodunu kullanarak değiştirmek istediğiniz şeyi vurgulayın ve ardından kaydı yapıştırın.

Sadece ikinci çözümü çok sonra bulduğum için bunu alışkanlık dışında kullanıyorum, örn.

yiw   " yank the whole word
viwp  " replace any word with the default register
  • YankRing . Bu eklenti ile <ctrl>+<p>, önceki numaralı kaydı yeni yapıştırdığınız kayıtla değiştirmek için tuş takımını kullanabilirsiniz .

Temelde yapıştıracağınız gibi gitmeye devam edersiniz, ancak varsayılan kaydın üzerine <C-P>yazdığınızı ve yapıştırmak istediğiniz şeyi kaybettiğinizi fark ettiğinizde , YankRing geçmişini bulmak ve değiştirmek için yapabilirsiniz!

Bunlardan birinin eklentileri olmalı ...



2

Windows sürümünde (muhtemelen Linux'ta da), sistemin kopyala / yapıştır arabelleğini kullanarak "*y(yani çift tırnak ve yıldız işareti ile yank komutundan önce ) çekebilirsiniz .

Daha sonra değiştirilebilir satırları normal olarak silebilir ve kopyalanan metni kullanarak yapıştırabilirsiniz "*p.


2

'Y'ank sonra' "_d'elete bir kara deliğe sonra 'p'aste' komutlarını uygularken sık sık hata yaparım. son kopyalanan metnin aktarıldığı 0 kaydı.


2

Emacs-evil kullanıcılar için, fonksiyon (evil-paste-pop)yapıştırıldıktan sonra tetiklenebilir ve kill-ring'deki önceki girişler arasında geçiş yapabilir. <C-p>Bağladığınızı varsayarsak (Boşluklarda varsayılan olarak), pardından <C-p>gerektiği kadar vurursunuz .


1

Dvorak kullanıcıları için, çok uygun bir yöntem, sadece aynı kaydırma tuşuna ve 1 olduğu için hızlı bir pembemsi hareketle + 1'e basabildiğiniz için, "_ kara delik kaydı yerine" 1 kayıt yerine "gereksiz yere silmek. Dvorak'ta hemen yukarıdaki anahtar "(PLUS d ise tüm komutu cehennem kadar hızlı yapar).

Daha sonra elbette, "1 kayıt, kolaylık nedeniyle başka şeyler için kullanılabilir, ancak metni değiştirmekten daha yaygın bir amacınız yoksa, kaydın oldukça iyi bir kullanımı olduğunu söyleyebilirim.


1

Bir metni sanal seçim ve yapıştırma ile değiştirdiğinizde, adsız kaydın üzerine yazmamakla ilgilenenleriniz için.

Kolay ve benim için en uygun olan aşağıdaki çözümü kullanabilirsiniz:

xnoremap <expr> p 'pgv"'.v:register.'y'

Buradaki cevaplardan (ve yorumlardan): Kayıtların üzerine yazmadan nasıl yapıştırılır

Önce seçimi geçtikten sonra yeni metinle seçim tekrar seçilir (gv). Şimdi görsel modda en son kullanılan kayıt (normalde adlandırılmamış kayıt, ancak yapıştırma için başka bir kayıt kullanırsanız yan etki ücretsiz çalışır). Ve sonra yeni değeri tekrar sicile çek.

Not: intellj idea eklentisi vim-simülasyonu ile de çalışan daha basit bir varyanta ihtiyacınız varsa bunu alabilirsiniz (olumsuz: yapıştırma için başka bir kayıt verilse bile adsız kaydın üzerine yaz):

vnoremap p pgvy



0

Vim'in zaman zaman pratikliğe göre karmaşıklığı tercih etmesi, kullanıcının eylemleri kopyalamak / silmek için kayıtlar uygulamasıyla yükümlüdür - çoğu zaman, kopyalanan şeyi yapıştırmak ve silinenleri "unutmak" ister.

Ancak, vim'in karmaşık kayıtlarıyla savaşmak yerine, onları daha uygun hale getirin: en son silmenizi saklamak için bir "varsayılan" kayıt seçin. Örneğin, d kaydına siler gönderin (ac-hoc kullanımı için ac'ı açık bırakın; d güzel bir anımsatıcıdır):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

Bu yaklaşım, silme işleminin silinmesini önler, ancak silme işlemini kaydetmeyi kaybetmez - biri, silinmiş olanı bir kara deliğe (kabul edilen cevapta olduğu gibi) kaybetmek yerine yapıştırabilir (geri). Yukarıdaki örnekte, bu hatırlama iki lider p eşlemesi ile yapılmıştır. Bu yaklaşımın bir yararı, size neyin yapıştırılacağını seçme yeteneği vermesidir: (a) az önce neyin çekildiğini veya (b) neyin yeni silindiğini.


0

0'dan 9'a kayıt olun, yaktığınız veya kestiğiniz en son şeylerdir ve silinmiş şeyleri vb. İÇERMEYİN. hala çektiğin / kestiğin son şey.

yiw #gogo varsayılan kayıt ve 0 kayıt

imlecin içinde bulunduğu kelimeyi sorar

silinmiş şeyler, vb varsayılan kayda gidecek, ancak kayıt 0

standart modda:

"0p # 0 kaydının içeriğini gir

ekleme modunda:

ctrl-r 0 # kaydın içeriğini girin 0

Ayrıca her zaman x lol kaydetmek / kesilmiş bir arkadaşı vardı.

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.