web-dev-qa-db-fra.com

Vim recherche et remplace le texte sélectionné

Disons que nous avons un texte et que je passe en mode visuel et sélectionne du texte. Comment puis-je rapidement rechercher le texte mis en surbrillance et le remplacer par quelque chose d'autre?

91
Gabriel Solomon

Essayez d’exécuter ce qui suit ou de le mettre dans votre .vimrc

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

En appuyant ctrl+r En mode visuel, vous serez invité à saisir le texte à remplacer. presse enter puis confirmez chaque changement que vous acceptez y ou décliner avec n.

Cette commande remplacera votre registre hafin que vous puissiez en choisir un autre (en modifiant hdans la commande ci-dessus en une autre lettre minuscule) que vous n'utilisez pas.

116
Mykola Golubyev

Cette cartographie simple et rapide permet de rechercher du texte mis en évidence de manière visuelle (sans écraser le registre h) ni utiliser le registre + dépendant du terminal:

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

Si vous n'aimez pas le ctrl-f changez-le selon vos préférences

Une fois le texte en surbrillance, vous pouvez toujours effectuer une substitution s en tapant simplement:

%s//<your-replacement-string>

... parce qu'une recherche vide sur la commande s utilise la dernière chaîne recherchée.

31
ErichBSchulz

La réponse acceptée fonctionne très bien sauf si vous avez sélectionné des caractères spéciaux. J'ai piraté deux scripts ( Jeremy Cantrell est posté ici & Peter Odding ') pour créer une commande qui vous permettra de sélectionner visuellement une chaîne que vous voulez trouver même si elle a une expression régulière personnages dedans.

" 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 - https://stackoverflow.com/questions/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>/

J'ai inclus cela dans mon vimrc si c'est plus utile à personne.

21
bryan kennedy

Celui-ci fonctionne également (au moins pour les sélections sur une seule ligne/sélections ne contenant pas de caractères spéciaux)

  • sélectionner le texte en mode visuel
  • tirez le texte avec y
  • :s/<C-r>0/

0 est le registre yank.

Comme d'autres personnes l'ont mentionné, il existe des moyens plus rapides pour le faire, mais si vous venez de commencer à apprendre Vim (comme moi), c'est l'un des moyens «génériques».

// edit: je viens de me rendre compte que l'approche 'register' échouera s'il y a des caractères comme des tabulations ou des nouvelles lignes ou des caractères / dans la sélection (je devrais traiter manuellement ces caractères d'une manière ou d'une autre pour que la commande :s fonctionne ):

enter image description here

16
colemik

De http://vim.wikia.com/wiki/Search_and_replace_in_a_visual_selection :

Lorsque le texte est sélectionné visuellement, appuyez sur: pour entrer une commande. La ligne de commande entrera automatiquement dans la plage:

:'<,'>

Vous pouvez entrer une commande telle que s/red/green/g pour remplacer chaque rouge par du vert dans toutes les lignes de la dernière sélection visuelle. La commande apparaîtra comme:

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

Pour répéter une commande Ex sur un bloc précédemment sélectionné, utilisez:: history. En d’autres termes, appuyez sur: puis sur, puis modifiez une commande précédente.

8
syvex

Mykola Golubyev, .__ Merci pour le tuyau! La suite utilise le registre "+" qui (en fonction de votre terminal) contient déjà le texte mis en surbrillance, en évitant d’utiliser le registre "h".

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

À partir de Vim 7.4, vous pouvez utiliser le mouvement gn qui permet de sélectionner des régions de texte correspondant au modèle de recherche actuel.

Après avoir utilisé cgn pour changer le texte de la correspondance sélectionnée (ou dgn à supprimer), vous pouvez utiliser . en mode normal pour répéter la commande et passer à la correspondance suivante.

Il y a un épisode de Vimcast montrant ce long métrage.

5
Dapeng Li

J'ai ceci dans mon 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>/

Cela va saisir la sélection visuelle et lancer une commande de substitution avec elle.

EDIT: Je dois préciser que cela ne fonctionne pas avec les sélections visuelles multilignes. Bien que GetVisual () n’ait aucun problème à le renvoyer, je ne sais pas comment le mettre correctement dans la ligne de commande. Si quelqu'un a des conseils sur la façon dont je pourrais le faire, veuillez commenter.

4
Jeremy Cantrell

Je ne pense pas que vous puissiez faire cela hors de la boîte. Mais beaucoup de gens aiment cette fonctionnalité, donc il y a des tonnes de macros et autres (je l'ai ajouté moi-même). Ici vous pouvez en ajouter, par exemple; appuyez simplement sur * pour rechercher la prochaine correspondance sur le texte sélectionné visuellement.

1
John Feminella

Exemple 1. Citer la sélection avec des étoiles, laissez le curseur au début de la sélection.

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

Exemple 2. Pipe le texte sélectionné avec base64:

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

Explication LHS:

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

Explication RHS:

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

Ma version courte préférée de ceci est

vnoremap s/y: s/"/

Ensuite, vous pouvez mettre une sélection en surbrillance et appuyer simplement sur s/pour lancer une commande de substitution.

0
alex

Je n'ai pas le représentant à commenter, alors j'ajoute encore une autre réponse ...

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

@dmd et @dotancohen: cela a fonctionné pour moi sans utiliser "h (utilise explicitement 0, qui est de toute façon la dernière position vengeance) et fonctionne avec PuTTY ssh -> mint (lmde); Je ne sais pas pour cent. Utilise également les commentaires @Niloct et @Nathan Friend pour supprimer la confirmation.

0
10'004