Ich benutze vim, um Latexdokumente zu bearbeiten. Oft möchte ich den Namen einer Variablen in etwas anderes ändern. Es ist jedoch etwas ärgerlich, wenn ich bei der Suche nach dem Variablennamen durch irrelevante Übereinstimmungen waten muss. Ich möchte nur in "Mathezonen" suchen, wie in der Tex-Syntaxdatei definiert. Gibt es eine einfache Möglichkeit, eine Suche auf einen bestimmten Syntaxbereich zu beschränken?
10
synIDattr()
, um Syntaxgruppen für das Zeichen unter dem Cursor zu erhalten. Sie können eine Funktion schreiben, die die Suche ausführt (oder ausführtnormal n
) und dann verwendetsynIDattr()
, um zu entscheiden, ob Sie an diesem Ort bleiben oder die Suche vorwärts fortsetzen möchten.Antworten:
Hier ist eine Funktion, die Sie ausprobieren können. Ich habe es nur ein wenig getestet, aber es scheint in Ordnung zu funktionieren.
Die Funktion ruft die Suchfunktion von Vim in einer Schleife auf, bis eine "normale" Übereinstimmung gefunden wird, die auch eine "qualifizierte" Übereinstimmung mit einem bestimmten Syntaxelement darstellt, oder bis das Ende des Puffers erreicht ist.
Es braucht zwei Argumente. Das erste ist das Suchmuster und wird unverändert an die
search()
Funktion von Vim weitergegeben . Sehen Sie,:help search()
wie diese Funktion funktioniert. Das zweite Argument ist der Name des Syntaxelements, nach dem Sie diese Übereinstimmungen filtern möchten. Dies kann auch ein Muster sein und wird als regulärer Ausdruck ohne Berücksichtigung der Groß- und Kleinschreibung verglichen.Um das Muster 'Alpha' in mathematischen Zonen zu finden, können Sie dies tun
Das
.
am Ende ist das Musteratom für jedes einzelne Zeichen, siehe:help /.
. Dies liegt daran, dass dort viele mathematische Zonensyntaxelemente usw. aufgerufentexMathZoneA
werdentexMathZoneB
.Die
search()
Funktion bewegt den Cursor zur nächsten "normalen" Übereinstimmung. Dann erhält unsere Funktion alle Syntaxelement-IDs für diese neue Cursorposition mitsynstack()
. Beim Durchlaufen werden die Namen der einzelnen Elemente nacheinander abgerufen und anhand dessyntaxitem
Arguments getestet . Siehe:help synstack()
und:help synIDattr()
. Wenn es eine 'qualifizierte' Übereinstimmung gibt, wird die Zeilennummer zurückgegeben. Wenn es das Ende des Puffers erreicht, ohne eine 'qualifizierte' Übereinstimmung zu finden, wird es zurückgegeben0
. Der Zweck der Funktion besteht darin, den Cursor auf die nächste 'qualifizierte' Übereinstimmung zu bringen, damit Sie dort eine Operation ausführen können. Es ist jedoch nützlich, "Zeilennummer oder 0" zurückzugeben, um anzugeben, ob es sinnvoll ist, die Funktion erneut aufzurufen, z Instanz, wenn Sie die Funktion wiederholt von einer anderen Funktion oder einem Makro aus aufrufen möchten.Ich habe mich für das
W
Flag entschieden,search()
weil es verhindert, dass das Ende des Puffers umwickelt wird. Andernfalls kann die Funktion hängen bleiben, da immer wieder dieselben "normalen" Übereinstimmungen gefunden werden, jedoch keine "qualifizierten" Übereinstimmungen.quelle
Wenn Ihre "mathematischen Zonen" durch ein syntaktisches Muster qualifiziert sind, z. B. die Zeichenfolge "math", können Sie zumindest Mustersequenzen verwenden , um eine Linie mit dem passenden Muster zu finden, wie in:
(Hinweis: Die beiden Muster können sich in unterschiedlichen Linien befinden!)
Dies beschränkt Ihre Übereinstimmungen möglicherweise nicht auf die Zonen - dafür müssten Sie das Ende der Zone identifizieren -, zeigt jedoch nur diese Übereinstimmungen nach einem anfänglichen Muster / math / an. Sie können die Suche nach dem nächsten Vorkommen mithilfe des Ex-Modus-Verlaufs (
:
up-arrow
enter
) wiederholen .Hinweis: ISTR, dass ich in früheren vim / vi-Versionen diese Methode auch direkt als Suchbefehl verwenden konnte (im Gegensatz zu einem Ex-Modus-Befehl),
/math//your pattern/
mit dem Vorteil, dass die Befehlen
und weniger eingegeben und verwendetN
werden müssen, aber ich kann sie nicht bestätigen das für meine aktuelle vim version.quelle
Wenn Sie nach der Zeichenfolge
foo
in$...$
oder suchen$$...$$
, sollte dies funktionieren:Dies verankert die Übereinstimmung mit einem
$
Zeichen, wählt jedoch nur die Zeichenfolge ausfoo
.Es ist keine einfache Lösung, aber man könnte ein
:global
+ verwenden:substitute
, um "mathematische Zonen" zu finden und darin zu suchen:Wenn
:substitute
Sie so tun, als wäre dies ein Suchbefehl, können Sie mit zum nächsten Vorkommen mit gehenn
und mit beendenq
. Sollten Sie versehentlich eine Substitution bestätigen, sollte dies kein Problem darstellen.Sie müssen die Liste in
%(
...)
auf die Namen der von Ihnen verwendeten mathematischen Umgebungen einstellen (die vollständige Liste ist etwas umfangreich :)align|alignat|displaymath|eqnarray|equation|flalign|gather|math|multline|subequations|xalignat|xxalignat
. Beachten Sie, dass ich hier ein sehr magic (\v
) Muster verwende.Erläuterung:
:global
ausführen , um eine Ex - Befehl (:s
) in jeder Zeile , wo die Muster matches (:help :global
)/\v
eine sehr magische Muster beginnen (:h /
,:h pattern
,:h magic
)\\begin\{
eine wörtliche entsprechen\begin{
%(align|alignat|displaymath)
einem dieser Wörter Match (:h /\%(
,:h /bar
)\}/
eine wörtliche übereinstimmen}
und das Muster beenden.+1,/\\end/-1
Ein Bereich, der aus der nächsten Zeile (von der gefundenen bis:global
) bis zur Zeile vor der vom Suchmuster gefundenen Zeile besteht/\\end
. Innerhalb dieses Bereichss/foo/&/gc
Suchen und Ersetzen jedes Vorkommens des Literalsfoo
durch sich selbst nach Bestätigung (:h :substitute
)quelle
\mathit
Variablennamen verwenden, ist es viel einfacher, sie zu finden.Wenn Sie suchen nach der Zeichenfolge ‚Morgen‘ innen Datei
/morning
dann enterund drücken nVorwärtsrichtung bewegenquelle
I would like to search only in "math zones"
Ihre Methode nach der gesamten Datei sucht und keine Forschungszone begrenzt.Es bleibt keine andere Wahl, als eine dedizierte Funktion dafür zu schreiben. Ich habe eine Funktion geschrieben, die die gewünschte Zeichenfolge durchsucht und nur dann stoppt, wenn:
Sie rufen es einfach mit der Zeichenfolge auf, die Sie suchen möchten.
Ich beabsichtige, eine ähnliche Funktion für GrammerousCheck zu schreiben, die nur bei Grammatikfehlern außerhalb der Mathematik stoppt.
quelle