Lorsque je recherche avec la /
commande en mode normal:
/\vSEARCHTERM
Vim commence la recherche à partir de la position du curseur et continue vers le bas, s'enroulant vers le haut. Cependant, lorsque je recherche et remplace à l'aide de la :substitute
commande:
:%s/\vBEFORE/AFTER/gc
Vim commence à la place en haut du fichier.
Existe-t-il un moyen pour que Vim effectue une recherche et un remplacement en commençant par la position du curseur et en retournant vers le haut une fois qu'il atteint la fin?
\vpattern
- motif `` très magique '': les caractères non alphanumériques sont interprétés comme des symboles spéciaux de regex (aucun échappement nécessaire)%
? Je ne vois aucune utilité raisonnable pour que vous parcouriez tout le dossier de toute façon.Réponses:
1. Il n'est pas difficile d'obtenir le comportement en utilisant une substitution en deux étapes:
Tout d'abord, la commande de substitution est exécutée pour chaque ligne à partir de la ligne actuelle jusqu'à la fin du fichier:
Ensuite, cette
:substitute
commande est répétée avec le même modèle de recherche, la même chaîne de remplacement et les mêmes indicateurs, à l'aide de la:&
commande (voir:help :&
):Ce dernier, cependant, effectue la substitution sur la plage de lignes de la première ligne du fichier à la ligne où la marque de contexte précédente a été définie, moins un. Étant donné que la première
:substitute
commande stocke la position du curseur avant de commencer les remplacements réels, la ligne adressée par''
est la ligne qui était la ligne actuelle avant l'exécution de cette commande de substitution. (L'''
adresse fait référence à la'
pseudo-marque; voir:help :range
et:help ''
pour plus de détails.)Notez que la deuxième commande (après le
|
séparateur de commande - voir:help :bar
) ne nécessite aucune modification lorsque le modèle ou les indicateurs sont modifiés dans le premier.2. Pour enregistrer un peu de frappe, afin d'afficher le squelette de la commande de substitution ci-dessus dans la ligne de commande, on peut définir un mappage en mode normal, comme ceci:
La
<c-b><right><right><right><right>
partie de fin est nécessaire pour déplacer le curseur au début de la ligne de commande (<c-b>
) puis quatre caractères vers la droite (<right>
× 4), le plaçant ainsi entre les deux premiers signes de barre oblique, prêt pour que l'utilisateur commence à taper le motif de recherche . Une fois que le motif souhaité et le remplacement sont prêts, la commande résultante peut être exécutée en appuyant sur Enter.(On pourrait envisager d'avoir
//
au lieu de///
dans le mappage ci-dessus, si l'on préfère taper le motif, puis taper soi-même la barre oblique de séparation, suivie de la chaîne de remplacement, au lieu d'utiliser la flèche droite pour déplacer le curseur sur une barre oblique de séparation déjà présente en commençant la pièce de rechange.)la source
:noremap <leader>R :,$s///gc\|1,''-&&<c-b><right><right><right><right>
. Il met:,$s///gc|1,''-&&
dans la ligne de commande avec le curseur entre les deux premiers signes de barre oblique. Une fois que vous avez tapé le modèle et le remplacement souhaités, vous pouvez exécuter la commande résultante en appuyant sur Entrée .Vous utilisez déjà une plage,,
%
qui est un raccourci pour1,$
désigner l'ensemble du fichier. Pour aller de la ligne actuelle à la fin que vous utilisez.,$
. La période signifie la ligne courante et$
la dernière ligne. La commande serait donc:Mais la
.
ligne ou courante peut être supposée donc peut être supprimée:Pour plus d'aide, consultez
la source
10:s/pattern/replace/gc
%
est un raccourci pour1,$
(Aide Vim =>
:help :%
égal à 1, $ (le fichier entier).).
est la position du curseur que vous pouvez faireA remplacer depuis le début du document jusqu'au curseur
etc
Je vous suggère fortement de lire le manuel sur la plage
:help range
car à peu près toutes les commandes fonctionnent avec une plage.la source
J'ai enfin trouvé une solution au fait que quitter la recherche revient au début du fichier sans écrire une fonction énorme ...
Vous ne croiriez pas combien de temps il m'a fallu pour trouver ça. Ajoutez simplement une invite pour savoir s'il faut envelopper: si l'utilisateur appuie à
q
nouveau, ne pas envelopper. Donc, en gros, quittez la recherche en appuyant surqq
au lieu deq
! (Et si vous voulez envelopper, tapez simplementy
.)En fait, j'ai mappé cela sur une touche de raccourci. Ainsi, par exemple, si vous souhaitez rechercher et remplacer chaque mot sous le curseur, à partir de la position actuelle, par
q*
:la source
q
,l
ou Esc ) et ne veulent pas continuer du haut, vous pouvez déjà appuyerq
ou Echap nouveau pour quitter la deuxième commande tout de suite. Autrement dit, l'ajout proposé de l'invite semble dupliquer efficacement la fonctionnalité déjà présente.yyyq
, de continuer à éditer, sans sauts désorientants. Maisyyyqq
c'est presque aussi bon, si vous considérez un double tap à peu près un seul robinet en termes de facilité d'utilisation.q
la deuxième pression ). Ce dernier laisse le curseur à la dernière occurrence remplacée (juste avant que la première neq
soit pressée).norm!``
commande::,$s/BEFORE/AFTER/gc|1,''-&&|norm!``
.Voici quelque chose de très grossier qui répond aux préoccupations concernant l'enroulement de la recherche avec l'approche en deux étapes (
:,$s/BEFORE/AFTER/gc|1,''-&&
) ou avec un intermédiaire "Continuer au début du fichier?" approche:Cette fonction utilise quelques hacks pour vérifier si nous devons aller vers le haut:
la source
Je suis en retard à la fête, mais je me suis trop souvent appuyé sur des réponses de stackoverflow aussi tardives pour ne pas le faire. J'ai rassemblé des conseils sur reddit et stackoverflow, et la meilleure option est d'utiliser le
\%>...c
modèle dans la recherche, qui ne correspond qu'après votre curseur.Cela dit, cela gâche également le modèle de la prochaine étape de remplacement et est difficile à taper. Pour contrer ces effets, une fonction personnalisée doit ensuite filtrer le modèle de recherche, le réinitialisant ainsi. Voir ci-dessous.
Je me suis disputé une cartographie qui remplace l'occurrence suivante et passe à la suivante après, et pas plus (c'était mon objectif de toute façon). Je suis sûr que, sur cette base, une substitution mondiale peut être élaborée. Gardez à l'esprit lorsque vous travaillez sur une solution visant quelque chose comme
:%s/.../.../g
ça, le modèle ci-dessous filtre les correspondances dans toutes les lignes à gauche de la position du curseur - mais est nettoyé après la fin de la substitution unique, donc il perd cet effet directement après, saute à la match suivant et peut ainsi parcourir tous les matchs un par un.fun! g:CleanColFromPattern(prevPattern) return substitute(a:prevPattern, '\V\^\\%>\[0-9]\+c', '', '') endf nmap <F3>n m`:s/\%><C-r>=col(".")-1<CR>c<C-.r>=g:CleanColFromPattern(getreg("/"))<CR>/~/&<CR>:call setreg("/", g:CleanColFromPattern(getreg("/")))<CR>``n
la source