Digamos que temos um texto e eu entro no modo visual e seleciono algum texto. Como faço rapidamente uma pesquisa pelo texto destacado e o substituo por outro?
Digamos que temos um texto e eu entro no modo visual e seleciono algum texto. Como faço rapidamente uma pesquisa pelo texto destacado e o substituo por outro?
Respostas:
Tente executar o seguinte ou colocar em seu .vimrc
vnoremap <C-r> "hy:%s/<C-r>h//gc<left><left><left>
Ao pressionar ctrl+ rno modo visual, você será solicitado a inserir o texto para substituir. Pressione entere confirme cada alteração com a qual você concorda you recusa n.
Este comando irá sobrescrever o seu registro hpara que você possa escolher outro (mudando hno comando acima para outra letra minúscula) que você não usa.
vmap * y:let @/ = @"<CR>selecionado é realçado.
<left><left><left>?
cde gc, você também terá que remover um dos <left>do final da linha.
Este mapeamento rápido e simples busca texto destacado visualmente (sem sobrescrever o registro h) e sem usar o registro dependente + do terminal:
" search for visually hightlighted text
vnoremap <c-f> y<ESC>/<c-r>"<CR>
Se você não gosta do ctrl-f mude-o de acordo com sua preferência
Assim que o texto for destacado, você sempre pode fazer uma ssubstituição simplesmente digitando:
%s//<your-replacement-string>
... porque uma pesquisa em branco no scomando usa a última string pesquisada.
control+fsempre seleciona o próximo caractere, bem como o que eu selecionei visualmente. Alguma ideia?
%s//<your-replacement-string>não parece funcionar para destacar algo como /tmp/file. torna<your-replacement-string>/tmp/file
Este também funciona (pelo menos para seleções em uma única linha / seleções que não contêm caracteres especiais)
y:s/<C-r>0/0 é o registro de puxão.
Como outras pessoas mencionaram, existem maneiras mais rápidas de fazer isso, mas se você acabou de começar a aprender Vim (como eu), esta é uma das maneiras 'genéricas'.
// editar: acabei de perceber que a abordagem de 'registro' falhará se houver caracteres como tabulações ou novas linhas ou /caracteres na seleção (eu teria que processar manualmente esses caracteres de alguma forma para que o :scomando funcione):

A resposta aceita funciona muito bem, a menos que você tenha caracteres especiais em sua seleção visual. Eu hackeei dois scripts ( Jeremy Cantrell postou aqui e Peter Odding ) para fazer um comando que permitirá a você selecionar visualmente uma string que deseja encontrar, mesmo que contenha caracteres regex especiais.
" 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>/
Eu incluí isso no meu vimrc se for mais útil para alguém.
vmap <C-r> <Esc>:%s/<c-r>=GetVisual()<cr>//g<left><left>(que apenas substitui todas no arquivo)
A partir do Vim 7.4, você pode usar o gnmovimento que seleciona regiões de texto que correspondem ao padrão de pesquisa atual.
Depois de usar cgnpara alterar o texto na correspondência atualmente selecionada (ou dgnexcluir), no modo normal, você pode usar .para repetir o comando e operar na próxima correspondência.
Há um episódio do Vimcast mostrando esse recurso.
Mykola Golubyev, Obrigado pela dica! A seguir usa o registro "+" que (dependendo do seu terminal) já contém o texto destacado, salvando de usar o registro "h".
vnoremap <C-r> <Esc>:%s/<C-r>+//gc<left><left><left>
De http://vim.wikia.com/wiki/Search_and_replace_in_a_visual_selection :
Quando o texto for selecionado visualmente, pressione: para inserir um comando. A linha de comando irá inserir automaticamente o intervalo:
:'<,'>
Você pode inserir um comando como s / red / green / g para substituir cada vermelho por verde em todas as linhas da última seleção visual. O comando aparecerá como:
:'<,'>s/red/green/g
Para repetir um comando Ex sobre um bloco previamente selecionado, use o: history. Ou seja, pressione: e então edite um comando anterior.
Eu tenho isso no meu vimrc:
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>/
Isso pegará a seleção visual e iniciará um comando de substituição com ela.
EDIT: Devo salientar que isso não funciona com seleções visuais multiline. Embora GetVisual () não tenha problemas para devolvê-lo, não tenho certeza de como colocá-lo corretamente na linha de comando. Se alguém tiver alguma dica de como posso fazer isso, comente.
Eu não acho que você pode fazer isso fora da caixa. Mas muitas pessoas gostam desse recurso, então há toneladas de macros e tal (eu mesmo adicionei). Aqui está um que você pode adicionar, por exemplo; apenas pressione *para pesquisar a próxima correspondência no texto selecionado visualmente.
Outras respostas são boas, mas não escapam a caracteres especiais. A resposta de @brian kennedy mostra um método para escapar, mas requer muito código. No caso de uma URL, por exemplo, o escape é obrigatório ou a pesquisa será interrompida em “:”.
Conforme escrito em vim.fandom.com/wiki/Search_for_visually_selected_text , você pode fazer um oneliner para pesquisar e escapar alguns caracteres. Você pode escapar dos personagens que quiser, eu escolhi escapar /\: :
vnoremap // y/\V<C-R>=escape(@",'/\:')<CR><CR>
Com este mapa, devo pressionar //no modo visual para pesquisar o texto atualmente selecionado em todo o buffer.
Minha versão curta favorita disso é
vnoremap s / y: s / "/
Então você pode destacar uma seleção e apenas apertar s / para iniciar um comando de substituição para ela.
"como um literal. <c-r>"funcionou
Não tenho representante para comentar, então estou adicionando mais uma resposta ...
vnoremap <C-r> "0y<Esc>:%s/<C-r>0//g<left><left>
@dmd e @dotancohen: funcionou para mim sem esgotar "h(usa explicitamente 0, que é a última posição de arrancada de qualquer maneira) e funciona com putty ssh -> mint (lmde); não sei sobre cent. Também usa comentários de @Niloct e @Nathan Friend para remover a confirmação.
Exemplo 1. Cite a seleção com estrelas, mantenha o cursor no início da seleção.
:%s,\%#\%V\_.*\%V/,**&**,c
Exemplo 2. Tubo de texto selecionado com base64:
:%s!\%#\%V\_.*\%V!\=system("base64 -w 0",@")!c
Explicação LHS:
\%# matches cursor
\%V matches inside the selection only
\_. matches any character.
\_.* matches beginning to end of selection.
Explicação RHS:
\=expr() Replace match with result of expr() for each substitution.
Eu esperava que houvesse uma maneira embutida no Vim para substituir uma palavra, sem ter que redigitar a palavra em primeiro lugar. Existe, embora funcione apenas para texto até um caractere de limite de palavra.
Depois de passar o mouse sobre a palavra, pressione *ou #para realçar a palavra e pule para o local anterior / seguinte dela (se você não quiser alterar os locais no arquivo, pressione a tecla oposta para voltar ao local você estava apenas em).
Depois é só digitar:
%s//<your-replacement-string>
Conforme mencionado na resposta de outra pessoa, se %sreceber um item em branco entre as barras, então usa a palavra pesquisada anteriormente. Ao pressionar *ou #, você está procurando a palavra sob o cursor, o que a torna a palavra pesquisada mais recentemente.
No final, são apenas seis ou sete pressionamentos de tecla + comprimento da palavra de substituição para fazer isso e não requer macro ou edição do seu .vimrc.
cemgc, Replace é feito de uma só vez em todo o buffer. Se você cometeu um erro e deseja revertê-lo, basta digitaruno modo de comando. Eu gosto mais dessa abordagem do que confirmar cada uma das substituições (isso acontece com ocmodificador).