J'utilise vim pour éditer des documents en latex. Souvent, je veux changer le nom d'une variable en autre chose. Cependant, c'est un peu ennuyeux de devoir parcourir des correspondances non pertinentes lorsque je recherche le nom de la variable. Je voudrais rechercher uniquement dans les "zones mathématiques" telles que définies dans le fichier de syntaxe tex. Existe-t-il un moyen simple de limiter une recherche à une région de syntaxe spécifique?
10
synIDattr()
pour obtenir des groupes de syntaxe pour le caractère sous le curseur. Vous pouvez écrire une fonction qui effectue (ou effectuenormal n
) la recherche , puis utilisesynIDattr()
pour décider de rester à cet emplacement ou de poursuivre la recherche.Réponses:
Voici une fonction que vous pourriez essayer. Je l'ai seulement testé un peu, mais cela semble fonctionner correctement.
La fonction appelle la fonction de recherche de Vim dans une boucle jusqu'à ce qu'elle trouve une correspondance «ordinaire» qui est également une correspondance «qualifiée» à un élément de syntaxe particulier, ou jusqu'à ce qu'elle atteigne la fin du tampon.
Il faut deux arguments. Le premier est le modèle de recherche et il est transmis tel quel à la
search()
fonction de Vim . Voir:help search()
comment cette fonction fonctionne. Le deuxième argument est le nom de l'élément de syntaxe sur lequel vous souhaitez filtrer ces correspondances. Cela peut également être un modèle et est comparé comme une expression régulière insensible à la casse.Pour trouver le motif «alpha» dans les zones mathématiques, vous pouvez le faire
À
.
la fin est l'atome de modèle pour n'importe quel caractère unique, voir:help /.
. En effet, de nombreux éléments de syntaxe de zone mathématique sont appeléstexMathZoneA
,texMathZoneB
etc.La
search()
fonction déplace le curseur sur la prochaine correspondance «ordinaire». Ensuite, notre fonction obtient tous les ID d'élément de syntaxe pour cette nouvelle position de curseur avecsynstack()
. En les parcourant, il récupère tour à tour le nom de chaque élément et le teste par rapport à l'syntaxitem
argument. Voir:help synstack()
et:help synIDattr()
. S'il existe une correspondance «qualifiée», elle renvoie le numéro de ligne. S'il atteint la fin du tampon sans trouver de correspondance «qualifiée», il revient0
. Le but de la fonction est de placer le curseur sur la prochaine correspondance «qualifiée» afin que vous puissiez y effectuer certaines opérations, mais il est utile de renvoyer «numéro de ligne ou 0» pour indiquer s'il est utile d'appeler à nouveau la fonction, par exemple par exemple si vous souhaitez appeler la fonction à plusieurs reprises à partir d'une autre fonction ou d'une macro.J'ai choisi d'utiliser l'
W
indicateur pour lesearch()
car il empêche de «contourner» la fin du tampon. Sinon, la fonction peut rester bloquée car elle continue de trouver les mêmes correspondances «ordinaires» mais aucune correspondance «qualifiée».la source
Dans le cas où vos "zones mathématiques" sont qualifiées par un motif syntaxique, par exemple, la chaîne "math", vous pouvez au moins utiliser des séquences de motifs pour trouver une ligne avec le motif correspondant, comme dans:
(Remarque: les deux modèles peuvent être sur des lignes différentes!)
Cela peut ne pas restreindre vos correspondances aux zones - pour cela, vous devez identifier la fin de la zone -, mais il n'affichera que les correspondances après un modèle / math / initial. Vous pouvez répéter la recherche de l'occurrence suivante en utilisant l'historique ex-mode (
:
up-arrow
enter
).Remarque: ISTR que dans les versions antérieures de vim / vi, j'ai également pu utiliser cette méthode directement comme commande de recherche (par opposition à une commande ex-mode)
/math//your pattern/
avec l'avantage de moins taper et utiliser les commandesn
etN
, mais je ne peux pas confirmer que pour ma version actuelle de vim.la source
Si vous recherchez la chaîne à l'
foo
intérieur de$...$
ou$$...$$
, cela devrait fonctionner:Cela ancre la correspondance à un
$
caractère mais ne sélectionne que la chaînefoo
.Ce n'est pas vraiment une solution facile, mais on pourrait utiliser un
:global
+:substitute
pour trouver des "zones mathématiques" et chercher à l'intérieur:En faisant semblant qu'il
:substitute
s'agit d'une commande de recherche, vous pouvez passer à l'occurrence suivante avecn
et quitter avecq
. Si vous confirmez une substitution par erreur, il ne devrait pas y avoir de problème.Vous devrez définir la liste à l'intérieur
%(
...)
aux noms des environnements mathématiques que vous utilisez (la liste complète est un peu lourde:)align|alignat|displaymath|eqnarray|equation|flalign|gather|math|multline|subequations|xalignat|xxalignat
. Notez que j'utilise\v
ici un motif très magique ( ).Explication:
:global
exécuter une commande Ex (:s
) sur chaque ligne où les matchs de motif (:help :global
)/\v
commencent un modèle très magique (:h /
,:h pattern
,:h magic
) désigner\\begin\{
un caractère\begin{
%(align|alignat|displaymath)
correspond à l' un de ces mots (:h /\%(
,:h /bar
) désigner\}/
un caractère}
et à la fin du modèle.+1,/\\end/-1
une plage composée de la ligne suivante (à partir de celle trouvée par:global
) jusqu'à la ligne précédant celle trouvée par le modèle de recherche/\\end
. Dans cette plage,s/foo/&/gc
rechercher et remplacer chaque occurrence du littéralfoo
par lui-même, après confirmation (:h :substitute
)la source
\mathit
autour des noms de variables, il est beaucoup plus facile de les trouver.Si vous recherchez la chaîne 'matin' dans le fichier,
/morning
puis enterappuyez sur npour avancerla source
I would like to search only in "math zones"
votre méthode recherche le fichier entier sans délimiter une zone de recherche.Il n'y a pas d'autre option que d'écrire une fonction dédiée pour cela. J'ai écrit une fonction qui recherche la chaîne que vous voulez et ne s'arrête que si:
Vous l'appelez simplement avec la chaîne que vous souhaitez rechercher.
J'ai l'intention d'écrire une fonction similaire pour GrammerousCheck qui ne s'arrête qu'aux erreurs de grammaire en dehors des mathématiques.
la source