From c8b2c8351fba3a94b39a57ca9d80494b86d5c2db Mon Sep 17 00:00:00 2001 From: James Strain Date: Mon, 17 Aug 2026 21:17:53 +1000 Subject: [PATCH] feat: add Nix syntax highlighting (#3110) * feat: add Nix syntax highlighting * fix: update Nix dependency hash * fix: update Nix dependency hash --------- Co-authored-by: Mohamed Boudra --- nix/npm-deps.hash | 2 +- package-lock.json | 18 +++++++++++++++++- packages/highlight/package.json | 2 ++ .../src/__tests__/highlighter.test.ts | 11 +++++++++++ .../highlight/src/__tests__/parsers.test.ts | 2 ++ packages/highlight/src/parsers.ts | 3 +++ 6 files changed, 36 insertions(+), 2 deletions(-) diff --git a/nix/npm-deps.hash b/nix/npm-deps.hash index 378a8e66f..be20d58e4 100644 --- a/nix/npm-deps.hash +++ b/nix/npm-deps.hash @@ -1 +1 @@ -sha256-XSalbyEP7UNN13EVpnvQHPxvEoxSDKuYhiaRg4Tyez4= +sha256-Ep6Z+J0urY1L66cXGe9bB6tQr8T3TY73GkLrvhf8FmA= diff --git a/package-lock.json b/package-lock.json index 3a2a05513..b95f6d4bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2554,7 +2554,6 @@ "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.3.tgz", "integrity": "sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", @@ -11155,6 +11154,21 @@ "@lezer/lr": "^1.0.0" } }, + "node_modules/@replit/codemirror-lang-nix": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@replit/codemirror-lang-nix/-/codemirror-lang-nix-6.0.1.tgz", + "integrity": "sha512-lvzjoYn9nfJzBD5qdm3Ut6G3+Or2wEacYIDJ49h9+19WSChVnxv4ojf+rNmQ78ncuxIt/bfbMvDLMeMP0xze6g==", + "license": "MIT", + "peerDependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@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/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", @@ -38563,6 +38577,7 @@ "name": "@getpaseo/highlight", "version": "0.4.0", "dependencies": { + "@codemirror/autocomplete": "6.20.3", "@codemirror/language": "6.12.4", "@codemirror/legacy-modes": "^6.5.3", "@lezer/common": "^1.5.0", @@ -38581,6 +38596,7 @@ "@lezer/xml": "^1.0.6", "@lezer/yaml": "^1.0.4", "@replit/codemirror-lang-csharp": "^6.2.0", + "@replit/codemirror-lang-nix": "^6.0.1", "lezer-elixir": "^1.1.2" }, "devDependencies": { diff --git a/packages/highlight/package.json b/packages/highlight/package.json index 9a9b8a6ad..67c0acd5b 100644 --- a/packages/highlight/package.json +++ b/packages/highlight/package.json @@ -27,6 +27,7 @@ "typecheck": "tsgo --noEmit" }, "dependencies": { + "@codemirror/autocomplete": "6.20.3", "@codemirror/language": "6.12.4", "@codemirror/legacy-modes": "^6.5.3", "@lezer/common": "^1.5.0", @@ -45,6 +46,7 @@ "@lezer/xml": "^1.0.6", "@lezer/yaml": "^1.0.4", "@replit/codemirror-lang-csharp": "^6.2.0", + "@replit/codemirror-lang-nix": "^6.0.1", "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 83bebd8ba..0e972e9b7 100644 --- a/packages/highlight/src/__tests__/highlighter.test.ts +++ b/packages/highlight/src/__tests__/highlighter.test.ts @@ -75,6 +75,17 @@ describe("highlightCode", () => { expect(stringToken?.style).toBe("string"); }); + it("highlights Nix code", () => { + const code = 'let message = "hello"; in message'; + const result = highlightCode(code, "default.nix"); + + const letToken = result[0].find((token) => token.text === "let"); + expect(letToken?.style).toBe("keyword"); + + const stringToken = result[0].find((token) => token.text.includes("hello")); + expect(stringToken?.style).toBe("string"); + }); + it("highlights TSX code with correct dialect", () => { const code = 'const el =
hello
;'; const result = highlightCode(code, "test.tsx"); diff --git a/packages/highlight/src/__tests__/parsers.test.ts b/packages/highlight/src/__tests__/parsers.test.ts index 16dea4b6c..43ac1dd03 100644 --- a/packages/highlight/src/__tests__/parsers.test.ts +++ b/packages/highlight/src/__tests__/parsers.test.ts @@ -21,6 +21,7 @@ describe("isLanguageSupported", () => { expect(isLanguageSupported("test.swift")).toBe(true); expect(isLanguageSupported("test.dart")).toBe(true); expect(isLanguageSupported("test.cs")).toBe(true); + expect(isLanguageSupported("test.nix")).toBe(true); expect(isLanguageSupported("test.ex")).toBe(true); }); @@ -60,6 +61,7 @@ describe("getSupportedExtensions", () => { expect(extensions).toContain("swift"); expect(extensions).toContain("dart"); expect(extensions).toContain("cs"); + expect(extensions).toContain("nix"); expect(extensions).toContain("json"); }); }); diff --git a/packages/highlight/src/parsers.ts b/packages/highlight/src/parsers.ts index 20d3b0578..a5caa079b 100644 --- a/packages/highlight/src/parsers.ts +++ b/packages/highlight/src/parsers.ts @@ -15,6 +15,7 @@ import { parser as rustParser } from "@lezer/rust"; import { parser as xmlParser } from "@lezer/xml"; import { parser as yamlParser } from "@lezer/yaml"; import { csharpLanguage } from "@replit/codemirror-lang-csharp"; +import { nixLanguage } from "@replit/codemirror-lang-nix"; import { parser as elixirParser } from "lezer-elixir"; import type { Parser } from "@lezer/common"; @@ -69,6 +70,8 @@ const languagesByExtension: Record = { dart: StreamLanguage.define(dart), // C# cs: csharpLanguage, + // Nix + nix: nixLanguage, // Elixir ex: language(elixirParser), exs: language(elixirParser),