J'ai un problème que je peux penser à deux approches générales pour résoudre, mais je ne connais pas les détails de l'une ou l'autre approche.
...
Level 1: cũng also
Level 1: và and
Level 1: như like; such as
Level 2: các plural marker
Level 2: của belonging to
...
Pour chaque ligne commençant par "Niveau n", je veux insérer un numéro commençant par "01". Pour plus de simplicité, ajoutons le numéro.
Approche 1: sélectionnez manuellement toutes les lignes de même niveau. Invoquez la magie que je vais bientôt apprendre.
Approche 2: Écrivez une recherche et remplacez qui correspond à toutes les lignes avec un niveau donné qui, à chaque correspondance, inclut un numéro dans le texte de remplacement, qui augmente d'une unité à chaque correspondance.
J'ai trouvé des questions similaires sur StackOverflow ou sur d'autres sites Vim, mais chacun semble avoir un ou plusieurs des problèmes suivants:
- Il s'agit d'insérer le numéro de ligne actuel plutôt qu'un nombre arbitraire mais incrémenté.
- Ne met pas à zéro le nombre.
- Ne fonctionne pas réellement pour les sélections sur mon Vim 7.4 fonctionnant sous Windows 7. (Celles-ci entraînent l'erreur
E481: No range allowed
.)
J'utilise gVim dans Windows avec mswin.vim mais une solution qui fonctionne sur toutes les installations Vim vanilla sans avoir à personnaliser la configuration pourrait être la meilleure.
Réponses:
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
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
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écimald
, occupant au moins 2 espaces2
et remplir avec 00
. 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 comptagei
et cela nous donne01
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
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 estI
, 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 tapiezI
(ou toute autre opération) vous-même en mode normal. nous utilisons l'!
afternormal
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 mots2w
, tirer jusqu'à ce que le ième caractère 'h'y" . i . "th
, aller à la fin de la ligne$
et collerp
.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.
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.
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 niveau
substitute(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:
Via la commande normale:
Exemple d'entrée:
Exemple de sortie:
la source
Vous pouvez créer à partir de https://stackoverflow.com/a/4224454/15934 pour mettre à zéro vos numéros.
Mais afin de simplifier l'action de remplissage des nombres, j'opterais pour une paire de fonctions et une commande:
Ensuite, sélectionnez vos lignes et tapez
:PrependNumber
(vous verrez:'<,'>PrependNumber
. [Remarque: La commande prend un paramètre facultatif: le motif avant lequel le numéro sera inséré]la source
line(".")
signifie pas «utiliser le numéro de ligne actuel»? C'était mon problème 1. avec les réponses précédentes que j'ai pu trouver.$HOME/vimfiles/plugin/whatevernameyouwish.vim
. Ou même votre$HOME/_vimrc
(nom de fichier Windows) si vous préférez (dans un premier temps). Si vous n'êtes pas sûr de ce que $ HOME est sur votre machine, demandez à vim ce qu'il pense que c'est ->:echo $HOME
:source
si le script vim est correctement installé dans le bon répertoire ({rtp} / plugin, ou {rtp} / ftplugin / {filetype} / ftplugin pour les plugins spécifiques au type de fichier).:source
c'est ce avec quoi nous avons dû jouer il y a plus d'une décennie et demie.Vous pouvez l'approcher en enregistrant une macro. En commençant par votre fichier d'origine, ajoutez la première instance au numéro.
Déplacez votre curseur sur
01
, sélectionnez et tirez dessus avecyiw
. Vous voulez maintenant enregistrer vos actions à partir de ce moment.qq/^Level 1<CR>P<C-A>A<space><esc>0yiwq
qq
Démarrer une macro dans le registre q/^Level 1<CR>
Rechercher une ligne commençant par "Niveau 1"P
coller avant le curseur (contient votre numéro)<C-A>
incrémente le nombreA<space><esc>
Insérez un espace après le numéro0
Aller au débutyiw
arracher le numéro actuelq
Mettre fin à la macroRépétez ensuite cette macro en utilisant
@q
.la source
<C-A>
contrôle + a? Cela sélectionne tout dans Vim sur Windows.