Semblable à la réponse sur https://vi.stackexchange.com/a/818/227 , vous pouvez utiliser la commande globale.
Avec lui, vous pouvez demander à vim de rechercher des lignes correspondant à un modèle, puis d'exécuter des commandes dessus.
Dans votre cas, vous souhaitez ajouter du texte aux lignes commençant par "Niveau N:", afin que notre commande globale puisse être
:g/^Level \d:/{COMMANDS}
Utilisation de la commande de substitution (remplacement d'expressions régulières) pour la commande
Les commandes sont plus amusantes. J'aime généralement faire un remplacement d'expression régulière pour des trucs comme ça, car il est facile d'utiliser des variables.
Exemple pour votre question
:let i = 1 | g/^Level \d:/s/^/\=printf("%02d ", i)/ | let i = i+1
Comment ça fonctionne
Dans la section de remplacement d'une commande de substitution peut être une expression.
La première chose que nous ferons est de définir une variable i
comme étant le numéro de départ. J'ai choisi 1, mais n'importe quel nombre fera l'affaire.let i = 1
Ensuite, nous exécutons notre commande globale, qui nous configure pour effectuer une action sur les lignes correspondantes. g/^Level \d:/
Nous allons demander à notre commande globale d'insérer la valeur et d'incrémenter notre compteur à l'aide de la commande de substitution et de la commande let. s/^/\=printf("%02d ", i)/ | let i = i+1
L'expression régulière de la commande de substitution trouve le début de la ligne ^
et la remplace par une expression, et notre expression sera le résultat d'une impression formatée. Comme dans le langage C, printf de vim prend les paramètres de formatage. %02d
signifie convertir un argument comme s'il s'agissait d'un nombre décimal d
, occupant au moins 2 espaces 2
et remplir avec 0 0
. Pour plus de détails et d'autres options de conversion (y compris la mise en forme à virgule flottante), voir :help printf
. Nous donnons à printf notre variable de comptage i
et cela nous donne 01
la première fois, 02
la deuxième fois, etc. Ceci est utilisé par la commande de substitution pour remplacer le début de la ligne, insérant efficacement le résultat de printf au début.
Notez que je mets un espace après le d: "%02d "
. Vous ne l'avez pas demandé dans la question (et je n'ai pas vu d'exemple de sortie), mais je soupçonnais que vous vouliez séparer le nombre du mot "Niveau". Supprimez l'espace de la chaîne donnée à printf pour avoir le numéro inséré juste à côté du L dans Level.
Enfin, cela let i = i + 1
incrémente notre compteur après chaque substitution.
Cela peut être appliqué généralement pour remplacer des parties de lignes qui sont appariées par d'autres critères par des données fonctionnelles arbitraires.
Utilisation de commandes normales combinées
C'est bon pour les insertions simples ou l'édition complexe. Comme avec substitute, nous utiliserons global pour faire correspondre, mais au lieu de substitution d'expression régulière, nous exécuterons une série d'opérations comme si elles étaient tapées par l'utilisateur.
Exemple pour votre question
:let i = 1 | g/^Level \d:/execute "normal! I" . printf("%02d ", i) | let i = i+1
Comment ça fonctionne
Les valeurs utilisées sont très similaires à celles du substitut (nous utilisons toujours printf pour formater notre nombre pour qu'il soit 0 rembourré avec 2 chiffres), mais l'opération est différente.
Ici, nous utilisons la commande d'exécution, qui prend une chaîne et exécute la chaîne comme une commande ex ( :help :exe
). Nous construisons une chaîne qui combine "normal! I" avec nos données, qui seront "normales! I01" la première fois et "normales! I02" la deuxième fois, etc.
La normal
commande effectue des opérations comme en mode normal. Dans cet exemple, notre commande normale est I
, qui insère au début de la ligne. Si nous l'avions utilisé, dd
cela supprimerait la ligne, o
ouvrirait une nouvelle ligne après la ligne correspondante. C'est comme si vous vous tapiez I
(ou toute autre opération) vous-même en mode normal. nous utilisons l' !
after normal
pour nous assurer qu'aucun mappage ne nous gêne. Tu vois :help :normal
.
Ce qui est alors inséré est la valeur de notre printf, comme dans le premier exemple d'utilisation de substitut.
Cette méthode peut être plus sophistiquée que l'expression régulière, car vous pouvez faire des choses comme execute "normal! ^2wy" . i . "th$p"
, qui iront au début du texte ^
, avancer de 2 mots 2w
, tirer jusqu'à ce que le ième caractère 'h' y" . i . "th
, aller à la fin de la ligne $
et coller p
.
C'est presque comme exécuter une macro, mais n'utilise pas réellement un registre et peut combiner des chaînes de toutes les expressions. Je trouve que c'est très puissant.
Approche où chaque niveau a son propre compteur
Vous voudrez peut-être que chaque niveau ait son propre compteur. Si vous connaissez le nombre maximal de niveaux à l'avance, vous pouvez effectuer les opérations suivantes (ajouter du code supplémentaire pour trouver le plus grand niveau n'est peut-être pas trop difficile, mais rendrait cette réponse trop longue. Cela devient aussi long que cela).
Tout d'abord, libérons i, au cas où nous l'aurions déjà utilisé comme entier. Nous ne pouvons pas convertir i en liste, nous devons le créer de cette façon.
:unlet! i
Ensuite, permet de définir i pour être une liste contenant le nombre de niveaux. Vous avez montré 2 dans votre question, mais supposons 10 pour le plaisir. Étant donné que l'indexation de liste est basée sur 0, et je ne veux pas déranger la correction pour 1 basée comme votre liste, nous allons simplement créer suffisamment d'éléments (11) et ne jamais utiliser l'index 0.
:let j = 0
:let i = []
:while j < 11 | let i += [1] | let j += 1 | endwhile
Ensuite, nous avons besoin d'un moyen d'obtenir le numéro de niveau. Heureusement, le substitut est également disponible en fonction, nous allons donc lui donner notre ligne et extraire le numéro de niveausubstitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")
Puisque i est maintenant une liste de 11 1
s (chaque indice est le compteur de notre niveau), nous pouvons maintenant ajuster l'un des exemples ci-dessus pour utiliser le résultat de cette substitution:
Via une commande de substitution:
:unlet! i | unlet! j | let j = 0 | let i = [] | while j < 11 | let i += [1] | let j += 1 | endwhile
:g/^Level \d:/let ind=str2nr(substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")) | s/^/\=printf("%02d ", i[ind])/ | let i[ind] += 1
Via la commande normale:
:unlet! i | unlet! j | let j = 0 | let i = [] | while j < 11 | let i += [1] | let j += 1 | endwhile
:g/^Level \d:/let ind=str2nr(substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")) | execute "normal! I" . printf("%02d ", i[ind]) | let i[ind] += 1
Exemple d'entrée:
Level 1: stuff
Level 1: Stuff
Some text
Level 3: Other
Level 1: Meh
Level 2: More
Exemple de sortie:
01 Level 1: stuff
02 Level 1: Stuff
Some text
01 Level 3: Other
03 Level 1: Meh
01 Level 2: More