Teilübereinstimmung der Vim-Syntax
Ich versuche, ein neues Zeilenzeichen in einer Vim-Syntaxdatei abzugleichen. Ich kann es zum Laufen bringen, wenn ich das Muster in Vim verwende. Wenn ich es jedoch in meine Syntaxdatei einfüge, wird nicht hervorgehoben, wann und wann ich eine neue Zeile habe es sollte.
Der Regex Teil , dass ich für neue Linie Spiel verwenden: \_s(auch versucht , mit \nmit: \(\n\|\s\))
Das Muster: [,(]\(\_s*\w\+:\)\?\_s*\zs\w\+
Vereinfachte Version des Paterns: [,(]\_s*\zs\w\+(Gleiches gilt für das Beispiel und den Zweck der Frage)
Syntaxdateicode im Inneren .vim/syntax/python.vim:
syn match pythonFunctionParam '[,(]\_s*\zs\w\+'
[...]
hi link pythonFunctionParam Error
[...]
let b:current_syntax = 'python'
Hier ist eine Beispiel-Testdatei zum Reproduzieren von try test.py::
a(matched_by_all=2, matched_by_all="anything")
b( matched_by_all=3,
matched_only_by_vim_search='test'
)
c(
matched_only_by_vim_search=3
matched_by_none="it's normal"
)
Wenn ich Vim Integrated Search ( /[,(]\_s*\zs\w\+) verwende, erhalte ich folgende Übereinstimmungen:
matched_by_all matched_by_all
matched_by_all
matched_only_by_vim_search
matched_only_by_vim_search
Also hat alles funktioniert hat erwartet
Wenn ich Syntax syn matchmit demselben regulären Ausdruck verwende, erhalte ich unterschiedliche Übereinstimmungen (weniger Übereinstimmungen):
matched_by_all matched_by_all
matched_by_all
Haben Sie sehen können, wenn es eine (oder ,in der gleichen Zeile gibt, wird es übereinstimmen, aber nicht, wenn es eine neue Zeile ist.
Meine Frage lautet also: Wie erhalte ich die gleiche Übereinstimmung in meiner Syntaxdatei?
Antworten
Sieht aus wie vim Syntax Match Regexp Engine nicht mag \zsund \_s. Wenn Sie entfernen \zs, können Sie Übereinstimmungen sehen:
Ich würde mit einem anderen Ansatz gehen:
- Definieren Sie einen transparenten Funktionsaufrufbereich, der Funktionsparameter enthält
- Definieren Sie den enthaltenen Funktionsparameter
syn region pythonFunctionCall start='\k\+\_s*(\zs' end='\ze)' contains=pythonFunctionParam transparent keepend
syn match pythonFunctionParam '\k\+\(\s*=\s*[^,]\+\)\?' contained
hi link pythonFunctionParam Error
HINWEIS: pythonFunctionParam ist nur ein einfaches Beispiel, das Sie optimieren können.
Es gibt eine explizite Ausnahme davon, wie \zseine Syntaxübereinstimmung funktioniert, da sie in derselben Zeile übereinstimmen muss, in der das Muster beginnt.
Siehe :help syn-multi-line:
Die Muster können "\ n" enthalten, um mit einem Zeilenende übereinzustimmen. Meistens funktioniert dies wie erwartet, es gibt jedoch einige Ausnahmen.
Wenn Sie ein Startmuster mit einem Versatz verwenden, darf der Beginn des Spiels nicht in einer folgenden Zeile beginnen. Die Hervorhebung kann jedoch in einer folgenden Zeile beginnen. Die Verwendung des
\zsElements erfordert auch, dass der Beginn des Spiels nicht in eine andere Zeile verschoben wird.
Sie können dies umgehen, indem Sie stattdessen ein Look-Behind-Match mit einer Breite von Null verwenden:
syn match pythonFunctionParam '\([,(]\_s*\)\@<=\w\+'
Beachten Sie jedoch, dass diese Art von Match tendenziell teurer ist. Wenn Sie eine verwenden, versuchen Sie, deren Umfang einzuschränken. Die Syntax-Engine in Vim bietet auch andere Mechanismen, mit denen Sie Ihre Übereinstimmungen eingrenzen können. Beispielsweise können Sie bestimmte Gruppen nur dann abgleichen, wenn sie in bestimmten anderen Gruppen auftreten. Dies kann dazu beitragen, diese Art von Syntax mithilfe einfacherer Übereinstimmungen zu implementieren.