HervéRenault.fr

logo de Vim

Saisies répétitives dans Vim

Imaginons que j'ai ce genre de fichier

dans lequel je veux remplacer .mp4 par .jpg dans les balises img uniquement :

<ul>
    <li><a href="11111111.jpg"><img src="11111111.jpg"></a></li>
    <li><a href="22222222.jpg"><img src="22222222.jpg"></a></li>
    <li><a href="33333333.mp4"><img src="33333333.mp4"></a></li>
    <li><a href="444444.jpg"><img src="444444.jpg"></a></li>
    <li><a href="555555.mp4"><img src="555555.mp4"></a></li>
    <li><a href="666666.mp4"><img src="666666.mp4"></a></li>
    <li><a href="77777777.jpg"><img src="77777777.jpg"></a></li>
</ul>
        

Je veux obtenir :

<ul>
    <li><a href="11111111.jpg"><img src="11111111.jpg"></a></li>
    <li><a href="22222222.jpg"><img src="22222222.jpg"></a></li>
    <li><a href="33333333.mp4"><img src="33333333.jpg"></a></li>
    <li><a href="444444.jpg"><img src="444444.jpg"></a></li>
    <li><a href="555555.mp4"><img src="555555.jpg"></a></li>
    <li><a href="666666.mp4"><img src="666666.jpg"></a></li>
    <li><a href="77777777.jpg"><img src="77777777.jpg"></a></li>
</ul>
        

Première possibilité, utiliser une commande rechercher-remplacer

C'est la possibilité qui me vient en premier à l'esprit : :%s/\(mp4.*\)mp4/\1jpg/ comme on peut faire avec sed ou Perl ou tout langage qui gère les expressions régulières. Mais il y a d'autres possibilités qui sont vraiment propres à Vim et que je n'utilise pas assez. J'écris cet aide-mémoire pour y penser plus souvent.

Deuxième possibilité, utiliser la commande .

qui sert justement à répéter la dernière modif, comme ceci :

Troisième possibilité, utiliser une macro

Parce que si j'ai 100 lignes dans mon fichier, ça va devenir fastidieux.

Bref, c'est pas simple 😅 mais je trouve ça assez amusant et ça peut parfois être utile alors je le note ici.

Remarques :

Imaginons maintenant que j'ai le bloc de code suivant :

$this->set('foo', 'bidule');
$this->set('bar', 'machine');
$this->set('bazzz', 'truc');
$this->set('feeeeeh', 'chose');

Et imaginons que je veux ajouter true en troisième paramètre de chaque appel de set pour obtenir :

$this->set('foo', 'bidule', true);
$this->set('bar', 'machine', true);
$this->set('bazzz', 'truc', true);
$this->set('feeeeeh', 'chose', true);

Je peux là encore utiliser une substitution avec une expression régulière mais je peux aussi utiliser une macro :

Ça semble un peu "overkill" pour quelques lignes mais avec l'habitude, je ne suis pas sûr que ça soit moins rapide que faire la modif à la main sur chaque ligne.

Enfin, pour ajouter une ligne sous toutes celles qui matchent "ba"

Par exemple pour ajouter cette ligne : echo 'coucou';

En une seule commande : g/ba/normal! oecho 'coucou';

Résultat :

$this->set('foo', 'bidule', true);
$this->set('bar', 'machine', true);
echo 'coucou';
$this->set('bazzz', 'truc', true);
echo 'coucou';
$this->set('feeeeeh', 'chose', true);

Note : ça peut être lent s'il y a beaucoup d'occurences à traiter dans le fichier (par exemple plus de 100)