it-swarm.com.de

Erweiterung der JavaScript-Syntax im Monaco Editor mit vollständiger Integration

Ich versuche, Monaco Editor zu erweitern, um Benutzern das Schreiben in einer Mischung aus JavaScript und einer anderen Sprache zu ermöglichen. Dabei werden Trennzeichen verwendet, um sie in derselben Datei zu trennen, ähnlich wie Markdown das Schreiben mehrerer Sprachen mithilfe von Fenced-Code-Blöcken ermöglicht.

Der Unterschied besteht darin, dass ich alle anderen IDE Funktionen, die Monaco für JavaScript integriert hat, beibehalten möchte, z. B. Flusen (über Diagnose ), intelligente automatische Vervollständigung , Zur Definition springen , Hilfe zur automatischen Formatierung und jede andere IDE Funktion, die mit Monacos integriertem JavaScript-Modus geliefert wird. Ich möchte, dass diese Funktionen weiterhin im JavaScript-Teil des von Monaco bearbeiteten Codes funktionieren und für den untergeordneten Sprachenteil deaktiviert sind.

Mein erster Versuch war, setMonarchTokensProvider aufzurufen und eine modifizierte Version von TypeScript's Tokenizer-Regeln zu übergeben. Konkret konnte ich der Root-Regel den Beginn-Zaun-Begrenzer hinzufügen und eine neue Regel für die Sub-Sprache erstellen, genauso wie in der Dokumentation für Monarch (Monacos Syntax Highligher) Beschreibt, using @nextEmbedded . (Zu Testzwecken habe ich CSS als eingebettete Sprache hartcodiert.)

Wenn ich setMonarchTokensProvider für die Sprache "javascript" aufrufe, ignoriert es diesen Syntax-Hervorhebungs-Tokenizer vollständig und färbt die Code-Zäune von CSS als ungültiges JavaScript ein, was darauf hinweist, dass Sie den integrierten JavaScript-Modus auf diese Weise nicht überschreiben können .

Wenn ich setMonarchTokensProvider mit einer neuen Sprache (z. B. "mylang") aufrufe und den Editor auf die Verwendung dieser Sprache einstelle, wird für diese CSS-in-JS-Hybridsprache die korrekte Syntaxhervorhebung (!) Bereitgestellt. Aber alle anderen erweiterten Funktionen, die im JavaScript-Modus gefunden wurden, sind nicht mehr vorhanden. Der Editor verfügte nicht über eine intelligente automatische Vervollständigung für Methoden, die für Klassen in derselben Datei definiert wurden, oder über eine In-Editor-Fehlerberichterstattung für ungültige Syntax oder eines seiner Markenzeichen. JavaScript IDE features .

Daher war mein nächster Versuch, die TypeScript-Definition des vorinstallierten Monaco-Codes so zu ändern, dass sie meine benutzerdefinierten Syntaxhervorhebungsregeln enthält. Dadurch wurde mein CSS-in-JS-Code vollständig (!) Hervorgehoben, als die Sprache auf "TypeScript" gesetzt wurde. Undließen alle anderen Funktionen intakt (!), Einschließlich Diagnoseberichte (Live-Validierung und Unterstreichung von Fehlern). , Auto-Vervollständigung, alles! (Ich habe es nicht mit "Javascript" versucht, aber es ist sicher anzunehmen, dass es wahrscheinlich funktioniert, oder es ist trivial, um es zum Laufen zu bringen, da JavaScript tatsächlich als Variantenkonfiguration des TypeScript implementiert ist Modus in Monaco .)

Leider wurde auch der gesamte CSS-Teil, einschließlich des umgebenden Zauns, als ungültiger JavaScript-Code betrachtet.

The thing almost working.

Ich weiß, dass dies theoretisch machbar ist, da Sie im HTML-Modus CSS oder JS mit vollständiger Unterstützung für die ordnungsgemäße Validierung und automatische Vervollständigung sowie für alle anderen IDE -Funktionen einbetten können. Grundsätzlich funktioniert jede untergeordnete Sprache in einer HTML-Datei wie in einer eigenen Datei: HTML-Features im Stammverzeichnis der Datei, CSS-Features in Style-Tags, JS-Features in Script-Tags.

Wenn Sie sich jedoch mit der Implementierung des TypeScript-Plugins in Monaco befassen, ist nicht klar, wo Sie mit der Bearbeitung beginnen sollen, entweder als Benutzer der Bibliothek in Monaco oder indem Sie sie forken und bei Bedarf patchen. Ich habe versucht, den DiagnostcsAdapter [sic] und das Tracing dort zu ändern, wo er tatsächlich implementiert ist, aber ich bin zwei Funktionsaufrufe tief hängen geblieben, wo es scheint, als ob ich ein Versprechen der Syntaxvalidierung das zurückgibt Ein Wert, der später verwendet wird , aber die Implementierung von getSyntacticDiagnostics schält nur die Arbeit zu einer anderen Implementierung, die ich nicht finden kann anderswo im Repo , noch in den Monaco-Sprachen repo oder der vscode repo .

5
Steven Degutis

Nach dem Schöpfer von Monaco:

Architektonisch können Sie Folgendes tun:

  • benutze monaco-editor-core direkt
  • definieren Sie eine neue Sprache für den Editor
  • geben Sie monaco-TypeScript ein und ändern Sie es, um mit Ihrer neu definierten Sprach-ID zu arbeiten. Ändern Sie anschließend den TS-Sprach-Hostcode, um die ursprünglichen Modelle nicht an TypeScript zu übergeben, sondern führen Sie zunächst einen Vorprozess aus, bei dem Ihre benutzerdefinierte Sprache aus dem Text entfernt wird, und geben Sie dann nur gültiges TypeScript an den TS-Compiler weiter. Eine Idee ist, jedes Zeichen, das Sie entfernen, durch ein Leerzeichen zu ersetzen. Dadurch bleibt die gesamte Arbeit zur Positions-/Offsetberechnung ohne großen Aufwand für Sie.

Viel Glück!

0
Steven Degutis

Ich mache das Gleiche. Meine Lösung besteht darin, Nicht-JS-Code in einen Blockkommentar einzufügen:

regularJsCode()
/* 
[your-syntax-identifying-start-token]
place any syntax you want here
[your-syntax-identifying-end-token]
*/
regularJsCode()

Dann können Sie es mit Ihren Tools, Parsern, IDE -Erweiterungen usw. verarbeiten. Und der coolste Teil, den Sie machen können, ist VSCode, um es syntaktisch hervorzuheben, so wie Sie möchten, damit es nicht wie ein Hack aussieht.

Dieser Ansatz ist vorzuziehen, da Ihre JS-Datei immer noch eine zu 100% gültige JS-Datei ist.

Wenn Sie Ihre Syntax dennoch nicht in Kommentare einfügen möchten, sollten Sie eine eigene Dateierweiterung wie .jsx/.tsx erstellen. In der Praxis bedeutet dies, dass Sie VSCode-Erweiterung mit Sprachserver und so weiter erstellen müssen. Das ist nicht so einfach, aber die Dokumentation ist gut. Sie können Ihren eigenen JS-Markierungscode in Ihrer VSCode-Erweiterung mithilfe des Sprachservers zusammenstellen: https://github.com/sourcegraph/javascript-TypeScript-langserver

2