diff --git a/src/editor/core/cm/languages.test.ts b/src/editor/core/cm/languages.test.ts index c6e71b62..5ca460d6 100644 --- a/src/editor/core/cm/languages.test.ts +++ b/src/editor/core/cm/languages.test.ts @@ -24,6 +24,30 @@ describe("language modes", () => { ]); }); + it("parses YAML into large tree buffers and highlights mappings after comment lines", async () => { + for (const path of ["/p/application.yml", "/p/compose.yaml"]) { + const support = await loadSupport(findLanguageDescription("YAML", path)!); + // @lezer/yaml can invert a node's range on a tree buffer boundary; one buffer avoids it. + expect((support!.language.parser as unknown as { bufferLength: number }).bufferLength).toBe(1 << 16); + } + const support = await loadSupport(findLanguageDescription("YAML", "/p/application.yml")!); + const source = "spring:\n datasource:\n # driver: a\n # url: b\n driver: c # d\n url: e\n"; + const found: Array<[string, string]> = []; + highlightTree( + support!.language.parser.parse(source), + tagHighlighter([ + { tag: t.lineComment, class: "comment" }, + { tag: t.definition(t.propertyName), class: "key" }, + ]), + (from, to, style) => found.push([source.slice(from, to), style]), + ); + expect(found.filter(([, style]) => style === "comment").map(([text]) => text)).toEqual([ + "# driver: a", + "# url: b", + "# d", + ]); + }); + it("recognizes AsciiDoc files and loads their lightweight syntax mode", async () => { for (const path of ["/docs/guide.adoc", "/docs/guide.asciidoc"]) { const description = findLanguageDescription("AsciiDoc", path); diff --git a/src/editor/core/cm/languages.ts b/src/editor/core/cm/languages.ts index 2c61f901..5bf64848 100644 --- a/src/editor/core/cm/languages.ts +++ b/src/editor/core/cm/languages.ts @@ -115,6 +115,21 @@ const OWN_MODES = [ load: () => import("./erb").then((m) => m.erb()), }), LanguageDescription.of({ name: "JSP", load: () => import("./jsp").then((m) => m.jsp()) }), + LanguageDescription.of({ + name: "YAML", + alias: ["yml"], + extensions: ["yaml", "yml"], + load: async () => { + const support = await languageData.find((l) => l.name === "YAML")!.load(); + // @lezer/yaml can give a mapping that follows comment lines an inverted range when it + // lands on a tree buffer boundary (1024 entries by default); highlighting then skips + // the whole mapping. Larger buffers keep ordinary YAML files in one. + return new LanguageSupport( + (support.language as LRLanguage).configure({ bufferLength: 1 << 16 }), + support.support, + ); + }, + }), ]; const BATCH_KEYWORDS = new Set([