Vim arama ve seçilen metni değiştirme


109

Diyelim ki bir metnimiz var ve ben görsel moda giriyorum ve bir metin seçiyorum. Vurgulanan metni nasıl hızlı bir şekilde arar ve başka bir şeyle değiştiririm?

Yanıtlar:


135

Aşağıdakileri gerçekleştirmeyi deneyin veya .vimrc

vnoremap <C-r> "hy:%s/<C-r>h//gc<left><left><left>

Görsel modda ctrl+ r'ya basarak , değiştirilecek metni girmeniz istenecektir. Tuşuna basın enterve ardından kabul ettiğiniz yveya reddettiğiniz her değişikliği onaylayın n.

Bu komut, kayıt defterinizi geçersiz kılar, hböylece kullanmadığınız diğerini ( hyukarıdaki komutta başka bir küçük harfle değiştirerek) seçebilirsiniz.


13
Eğer atlarsanız cin gc, tüm tampon içerisinde bir defada yapılır değiştirmek yeterlidir. Bir hata yaptıysanız ve bunu geri almak istiyorsanız, ukomut kipinde yazmanız yeterlidir. Bu yaklaşımı, değiştirmelerin her birini onaylamaktan daha çok seviyorum (bu cdeğiştiriciyle olur ).
Niloct

3
vmap * y:let @/ = @"<CR>seçili vurgulanır.
kev

8
Amacı ne <left><left><left>?
aymericbeaumet

7
İmleci iki eğik çizgi arasına getirmek için @aymericbeaumet, böylece değiştirme kelimesi kolayca yazılabilir.
mcabrams

5
Eğer kaldırma hakkında Niloct önerisi @ alırsak Not olduğu cgelen gc, ayrıca birini kaldırmak gerekecek <left>hattın sonundan 's.
Nathan Friend

36

Görsel olarak vurgulanan metin için (h yazmacının üzerine yazmadan) ve terminale bağlı + yazmacı kullanmadan bu hızlı ve basit haritalama araması:

" search for visually hightlighted text
vnoremap <c-f> y<ESC>/<c-r>"<CR>   

Ctrl-f'yi beğenmediyseniz, tercihinize göre değiştirin

Metin vurgulandıktan sonra, her zaman ssadece şunu yazarak bir ubstitution yapabilirsiniz :

%s//<your-replacement-string>

... çünkü skomutta boş bir arama, en son aranan dizeyi kullanır.


Bunu vim yapılandırmamda kullandığımda, control+fher zaman bir sonraki karakteri ve görsel olarak seçtiğim karakteri seçer. Herhangi bir fikir?
Robert Mark Bram

%s//<your-replacement-string>gibi bir şeyi vurgulamak için işe yaramıyor gibi görünüyor /tmp/file. sadece<your-replacement-string>/tmp/file
naisanza

29

Bu da işe yarar (en azından tek bir satırdaki seçimler / herhangi bir özel karakter içermeyen seçimler için)

  • metni görsel modda seçin
  • metni ile çekin y
  • :s/<C-r>0/

0 yank kaydıdır.

Başkalarının da bahsettiği gibi, bunu yapmanın daha hızlı yolları var, ancak Vim'i öğrenmeye yeni başladıysanız (benim gibi), bu 'genel' yollardan biridir.

// edit: Seçimde sekme, satırsonu veya /karakter gibi karakterler varsa 'kayıt' yaklaşımının başarısız olacağını yeni fark ettim (bu karakterleri bir şekilde manuel olarak işlemem gerekirdi.:s komutun çalışması ):

görüntü açıklamasını buraya girin


2
Çok basit. Tanrım, neden wikide yer almıyor. Hadi ... Cevabınız için teşekkürler!
Benyamin Limanto

2
Bu, hala Vim öğrenme eğrisinin erken döneminde olanlarımız için ideal cevaptır. Kişiselleştirmenin bir güç olduğunu biliyorum, ancak karmaşık bir komut dosyasını kopyalayıp vimrc'ime yapıştırmak ve bu kadar basit bir problem için nasıl bir araya geleceğini anlamak istemiyorum. Bu cevap bana ctrl-R'nin bir yazmacı attığını öğretti, bu da diğer bağlamlarda hatırlamak için kullanışlı olacak.
nivek

26

Kabul edilen cevap, görsel seçiminizde özel karakterler olmadıkça harika çalışıyor. İçinde özel normal ifade karakterleri olsa bile bulmak istediğiniz bir dizeyi görsel olarak seçmenize izin verecek bir komut oluşturmak için iki komut dosyasını ( Jeremy Cantrell 'in burada ve Peter Odding ' in) bir araya getirdim .

" Escape special characters in a string for exact matching.
" This is useful to copying strings from the file to the search tool
" Based on this - http://peterodding.com/code/vim/profile/autoload/xolox/escape.vim
function! EscapeString (string)
  let string=a:string
  " Escape regex characters
  let string = escape(string, '^$.*\/~[]')
  " Escape the line endings
  let string = substitute(string, '\n', '\\n', 'g')
  return string
endfunction

" Get the current visual block for search and replaces
" This function passed the visual block through a string escape function
" Based on this - /programming/676600/vim-replace-selected-text/677918#677918
function! GetVisual() range
  " Save the current register and clipboard
  let reg_save = getreg('"')
  let regtype_save = getregtype('"')
  let cb_save = &clipboard
  set clipboard&

  " Put the current visual selection in the " register
  normal! ""gvy
  let selection = getreg('"')

  " Put the saved registers and clipboards back
  call setreg('"', reg_save, regtype_save)
  let &clipboard = cb_save

  "Escape any special characters in the selection
  let escaped_selection = EscapeString(selection)

  return escaped_selection
endfunction

" Start the find and replace command across the entire file
vmap <leader>z <Esc>:%s/<c-r>=GetVisual()<cr>/

Bunu benim Eğer herhangi biri için daha yararlıysa bunu vimrc'ime .


2
çözüm için teşekkürler, birden fazla öneriyi birleştirerek, şunu elde ettim: vmap <C-r> <Esc>:%s/<c-r>=GetVisual()<cr>//g<left><left>(dosyadaki her şeyin yerine geçer)
Peter Butkovic

13

Vim 7.4'ten, gn mevcut arama modeliyle eşleşen metin bölgelerini seçen hareketi .

cgnMevcut seçili eşleşmedeki metni değiştirmek için kullandıktan sonra (veyadgn normal modda, silmek için), kullanabilirsiniz. komutu tekrarlamak ve bir sonraki maç çalışır.

Bu özelliği gösteren bir Vimcast bölümü var .


3
Bu harika bir cevap!
mauriciojost

Bu da harika. colemik yanıtı dışında. Muhteşem bir tane!
Benyamin Limanto

vay, iyi bir çözüm bulmak için derinlere göz attığınızda bulduğunuz sırlardan biri gibi, teşekkürler!
vdegenne

8

Mykola Golubyev, Bahşiş için teşekkürler! Aşağıda, (terminalinize bağlı olarak) vurgulanan metni içeren "+" kaydını kullanır ve "h" kaydını kullanarak kaydeder.

vnoremap <C-r> <Esc>:%s/<C-r>+//gc<left><left><left>

CentOS 5.x üzerindeki VIM 7.0'ımın + kaydı yok gibi görünüyor. Bu standart bir özellik mi?
dotancohen

3
CentOS makinesine Putty aracılığıyla eriştiğimi ve googling üzerine + 'nın pano kaydı olduğunu görüyorum. Putty bunu desteklemiyor! Yani bu cevap aslında terminale bağlıdır.
dotancohen

Merhaba, komutunuzu denedim ama benden sadece seçilen metni değil, tüm dosya boyunca belirtilen metnin oluşumlarını değiştirmemi istiyor
solalito

7

Gönderen http://vim.wikia.com/wiki/Search_and_replace_in_a_visual_selection :

Metin görsel olarak seçildiğinde, bir komut girmek için: tuşuna basın. Komut satırı, aralığı otomatik olarak girecektir:

:'<,'>

Son görsel seçimin tüm satırlarında her kırmızıyı yeşil ile değiştirmek için s / kırmızı / yeşil / g gibi bir komut girebilirsiniz. Komut şu şekilde görünecektir:

:'<,'>s/red/green/g

Daha önce seçilen bir blok üzerinde bir Ex komutunu tekrarlamak için: geçmişini kullanın. Yani, tuşuna basın ve ardından bir önceki komutu düzenleyin.


4
evet bu , seçilen alanda kırmızıyı yeşil ile değiştirir - çok kullanışlı, ancak operasyonun istediği şey değil.
ErichBSchulz

@ErichBSchulz Aslında bunu seçilen tüm satırlarda yapıyor. Yani, bir çizginin sadece bir kısmı seçilse bile, bunu tüm satıra yapacaktır.
Cully

1
Belki de OP sorusuna yanıt vermiyor, ancak bu, "arama ve görsel seçimle değiştir" aramama tam olarak yanıt veriyor, burada aramayı ve değiştirmeyi yalnızca görsel seçimle sınırlamak istiyorum, bu da bu soruyu getiriyor
icc97

5

Bu benim vimrc'imde var:

function! GetVisual() range
    let reg_save = getreg('"')
    let regtype_save = getregtype('"')
    let cb_save = &clipboard
    set clipboard&
    normal! ""gvy
    let selection = getreg('"')
    call setreg('"', reg_save, regtype_save)
    let &clipboard = cb_save
    return selection
endfunction

vmap <leader>z :%s/<c-r>=GetVisual()<cr>/

Bu görsel seçimi yakalayacak ve onunla bir ikame komutu başlatacaktır.

DÜZENLEME: Bunun çok satırlı görsel seçimlerle çalışmadığını belirtmeliyim. GetVisual () onu döndürmekle ilgili bir sorun yaşamasa da, komut satırına nasıl düzgün bir şekilde yerleştireceğimi bilmiyorum. Bunu nasıl yapabileceğim konusunda herhangi bir ipucu varsa, lütfen yorum yapın.


2

Bunu kutudan çıkarabileceğinizi sanmıyorum. Ancak pek çok insan bu özelliği sever, bu yüzden tonlarca makro var (bunu kendim ekledim). İşte ekleyebileceğiniz bir örnek; *görsel olarak seçilen metinde bir sonraki eşleşmeyi aramak için sadece tuşuna basın .


2

Diğer cevaplar iyidir ancak özel karakterlerden kaçmazlar. cevap @brian Kennedy kaçmak için bir yöntem gösterir ama çok kod gerektirir. Örneğin bir URL durumunda, çıkış zorunludur veya arama ":" üzerinde durur.

Vim.fandom.com/wiki/Search_for_visually_selected_text'te yazıldığı gibi , bazı karakterleri aramak ve bunlardan kaçmak için bir oneliner yapabilirsiniz. İstediğiniz karakterlerden kaçabilirsiniz, ben kaçmayı seçtim /\: :

vnoremap // y/\V<C-R>=escape(@",'/\:')<CR><CR>

Bu harita //ile, tüm arabellekte mevcut seçili metni aramak için görsel modda basmalıyım.


1

Bunun en sevdiğim kısa versiyonu

vnoremap s / y: s / "/

Ardından bir seçimi vurgulayabilir ve bunun için bir ikame komutu başlatmak için s / tuşuna basabilirsiniz.


Benim için işe yaramadı, gerçekmiş "gibi muamele gördü . <c-r>"yine de çalıştı
Josh Bodah

1

Yorum yapacak bir temsilcim yok, bu yüzden bir cevap daha ekliyorum ...

vnoremap <C-r> "0y<Esc>:%s/<C-r>0//g<left><left>

@dmd ve @dotancohen: bu benim için up kullanmadan çalıştı "h(açıkça 0 kullanır, ki bu zaten son yank pozisyonudur) ve macun ssh -> nane (lmde) ile çalışır; cent hakkında bilmiyorum. Ayrıca onayı kaldırmak için @Niloct ve @Nathan Friend yorumlarını kullanır.


1

Örnek 1. Seçimi yıldızlarla aktarın, imleci seçimin başında tutun.

:%s,\%#\%V\_.*\%V/,**&**,c 

Örnek 2. Seçili metni base64 ile boru hattı oluşturun:

:%s!\%#\%V\_.*\%V!\=system("base64 -w 0",@")!c

Açıklama LHS:

\%# matches cursor 
\%V matches inside the selection only
\_. matches any character.
\_.* matches beginning to end of selection.

Açıklama RHS:

\=expr()  Replace match with result of expr() for each substitution.

0

İlk başta kelimeyi yeniden yazmak zorunda kalmadan, bir kelimeyi değiştirmek için Vim'de yerleşik bir yol olmasını umuyordum. Sadece bir kelime sınır karakterine kadar olan metinler için çalışmasına rağmen var.

Fareyle sözcüğün üzerine geldiğinizde, sözcüğü vurgulamak ve sonraki / önceki konumuna atlamak için *veya tuşuna basın #(dosyadaki konumları değiştirmek istemiyorsanız, konuma geri dönmek için ters tuşa basın sen sadece).

Ardından şunu yazın:

%s//<your-replacement-string>

Başka bir kişinin cevabında belirtildiği gibi %s, eğik çizgiler arasında boş bir giriş alırsa, önceden aranan kelimeyi kullanır. *Veya düğmesine basarak# , imlecin altındaki kelimeyi en son aranan kelime haline getiren kelimeyi arıyorsunuz.

Sonunda, bunu gerçekleştirmek için yalnızca altı veya yedi tuş vuruşu + değiştirme kelimesi uzunluğu ve makro veya .vimrc.

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.