diff --git a/nix/npm-deps.hash b/nix/npm-deps.hash index be20d58e4..9dd302c37 100644 --- a/nix/npm-deps.hash +++ b/nix/npm-deps.hash @@ -1 +1 @@ -sha256-Ep6Z+J0urY1L66cXGe9bB6tQr8T3TY73GkLrvhf8FmA= +sha256-WblXeNn1wUUaxElDGNXHcWdvvHJhqp7LySanhLDv5lQ= diff --git a/package-lock.json b/package-lock.json index b95f6d4bf..0cd688576 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2573,6 +2573,54 @@ "@lezer/common": "^1.1.0" } }, + "node_modules/@codemirror/lang-css": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", + "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.1.7" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.12", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.12.tgz", + "integrity": "sha512-pw2ReWKUqSkbvh76RAT4NYxiogRu+PWkR2ukAwO9uOgrm8uipkzjtKKtNpyeAQwHOqxEeSvAXZ6vr3AfyB9y/w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.12" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.5.tgz", + "integrity": "sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, "node_modules/@codemirror/language": { "version": "6.12.4", "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.4.tgz", @@ -2596,6 +2644,18 @@ "@codemirror/language": "^6.0.0" } }, + "node_modules/@codemirror/lint": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.7.tgz", + "integrity": "sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.42.0", + "crelt": "^1.0.5" + } + }, "node_modules/@codemirror/search": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.1.tgz", @@ -11169,6 +11229,25 @@ "@lezer/lr": "^1.0.0" } }, + "node_modules/@replit/codemirror-lang-svelte": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@replit/codemirror-lang-svelte/-/codemirror-lang-svelte-6.0.0.tgz", + "integrity": "sha512-U2OqqgMM6jKelL0GNWbAmqlu1S078zZNoBqlJBW+retTc5M4Mha6/Y2cf4SVg6ddgloJvmcSpt4hHrVoM4ePRA==", + "license": "MIT", + "peerDependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.1", + "@codemirror/lang-html": "^6.2.0", + "@codemirror/lang-javascript": "^6.1.1", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/javascript": "^1.2.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/@replit/codemirror-vim": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@replit/codemirror-vim/-/codemirror-vim-6.3.0.tgz", @@ -38597,6 +38676,7 @@ "@lezer/yaml": "^1.0.4", "@replit/codemirror-lang-csharp": "^6.2.0", "@replit/codemirror-lang-nix": "^6.0.1", + "@replit/codemirror-lang-svelte": "^6.0.0", "lezer-elixir": "^1.1.2" }, "devDependencies": { diff --git a/packages/highlight/package.json b/packages/highlight/package.json index 67c0acd5b..9bb454fba 100644 --- a/packages/highlight/package.json +++ b/packages/highlight/package.json @@ -47,6 +47,7 @@ "@lezer/yaml": "^1.0.4", "@replit/codemirror-lang-csharp": "^6.2.0", "@replit/codemirror-lang-nix": "^6.0.1", + "@replit/codemirror-lang-svelte": "^6.0.0", "lezer-elixir": "^1.1.2" }, "devDependencies": { diff --git a/packages/highlight/src/__tests__/highlighter.test.ts b/packages/highlight/src/__tests__/highlighter.test.ts index 0e972e9b7..830d4e4ba 100644 --- a/packages/highlight/src/__tests__/highlighter.test.ts +++ b/packages/highlight/src/__tests__/highlighter.test.ts @@ -86,6 +86,38 @@ describe("highlightCode", () => { expect(stringToken?.style).toBe("string"); }); + it("highlights Svelte components across script, markup, and style", () => { + const code = [ + '", + "", + "{#if count > 0}", + ' {count}', + "{/if}", + "", + "", + ].join("\n"); + const result = highlightCode(code, "Counter.svelte"); + + expect(result[1].find((t) => t.text === "let")?.style).toBe("keyword"); + expect(result[1].find((t) => t.text === "number")?.style).toBe("type"); + + expect(result[4].find((t) => t.text === "if")?.style).toBe("keyword"); + expect(result[4].find((t) => t.text === "count")?.style).toBe("variable"); + + expect(result[5].find((t) => t.text === "span")?.style).toBe("tag"); + expect(result[5].find((t) => t.text === "class")?.style).toBe("attribute"); + expect(result[5].find((t) => t.text === "count")?.style).toBe("variable"); + + expect(result[9].find((t) => t.text === "badge")?.style).toBe("class"); + expect(result[10].find((t) => t.text === "color")?.style).toBe("property"); + }); + it("highlights TSX code with correct dialect", () => { const code = 'const el =