Vim: s replace les premières occurrences N <g sur une ligne

Dans vim, j'ai parfois l'occasion de replace les premières occurrences d'un match sur une ligne, mais pas tout le monde comme g ferait. par exemple:

 aaaaa 

à

 bbbaa 

Je sais que je pourrais utiliser :s/a/b/[enter]:[up][enter]:[up][enter] , mais c'est assez fastidieux à trois répétitions.
J'ai essayé:

  • :s/a/b/3g : vim se plaignait de caractères de fin.
  • :s/a/b/3 : change la première occurence sur cette et les deux lignes suivantes.
  • 3:s/a/b : identique au précédent.
  • :s/a/b/g3 : change toutes les occurrences sur cette et les deux lignes suivantes.
  • :3s/a/b : change la première occurrence sur la ligne 3.
  • :/a/,3/a/s/a/b : change la première occurrence sur chaque ligne entre la prochaine et la troisième ligne contenant a dans le file (invitant à l'inverse si nécessaire).
  • :/a/,/\([^a]*a\)\{3\}/s/a/b/ change la première occurrence sur chaque ligne entre ceci et la suivante avec 3 a s (et ceci n'aurait pas été facilement extensible à une search multi-caractères).

Et divers autres templates d'adressage, dont aucun n'a fonctionné. Je dois dire que j'ai appris beaucoup de choses sur le commandment de la :s essayer de find une réponse à ce problème, mais je n'ai toujours pas résolu.

Quelqu'un sait-il comment faire ça?

(points bonus pour une plage spécifique, par exemple, deuxième à quasortingème occurrences)

En se basant sur l' idée :s/pattern/replacement/gc de Samus_ (qui semble être le moyen le plus simple d'assurer un fonctionnement correct quand le pattern est contenu dans la string de rlocation), replace les 2ème à 4ème occurrences sur une seule ligne:

 :call feedkeys("nyyyq") | s/pat/ssortingng/gc 

feedkeys() est une fonction qui emstack la string d'input dans la queue d'input du keyboard. Le but est de faire le count à rebours afin de ne pas avoir à vous soucier de perdre le count ou de vous interrompre.

Pour un cas plus général, replace les Mème à Nème occurrences sur une seule ligne pour N supérieur ou égal à un très grand M :

 :call feedkeys(repeat("n", M-1) . repeat("y", N-M+1) . "q") | s/pat/ssortingng/gc 

Remplacez M et N par les valeurs que vous voulez (vous pouvez même laisser vim faire l'arithmétique mentale sortingviale si vous ne voulez pas le faire vous-même). Notez cela . est l'opérateur de concaténation de string de VimL. Évidemment, cela ne fait qu'save les frappes keyboard pour les gros M. Si vous utilisez cette fonctionnalité fréquemment, cela peut vous faire gagner du time pour mettre ce qui précède dans une command ou une fonction personnalisée, car c'est un peu à taper.

Pour la première question je ferais:

 :s/a/b && 

Le second est plus délicat, je ne connais pas le moyen de le faire automatiquement mais vous pouvez faire en sorte que vim vous invite à chaque match comme ceci:

 :s/a/b/gc 

Ensuite, vous répondez "non" aux n premiers matches et "oui" aux autres.

 aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa :3,6g/^/let i=0 | while i<3 | s/a/b/ | let i+=1 | endwhile aaaaa aaaaa bbbaa bbbaa bbbaa bbbaa aaaaa