From c13f6acfbe0824b090851274bffa5aeb00c346d3 Mon Sep 17 00:00:00 2001 From: "robopipi[bot]" <336283572+robopipi[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2026 10:45:55 +0100 Subject: [PATCH] Highlight .dart, .nix, and .groovy files in read/write views (#11790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `read` and `write` tool views find a file's language from its extension with `getLanguageFromPath()`. That function's extension table had no entries for Dart, Nix, or Groovy. Their highlight.js grammars are loaded at startup, but the lookup returned `undefined`, so these files were shown as plain uncolored text. This change adds `dart → dart`, `nix → nix`, `groovy → groovy`, and `gradle → groovy` to the table in `packages/coding-agent/src/modes/interactive/theme/theme.ts`. HTML export keeps its own separate extension map and a vendored highlight bundle without a Dart grammar. This change does not touch either. ## Testing - Added a test to `test/syntax-highlight.test.ts` that checks the new extension mappings. It fails without the fix and passes with it. - `node ../../node_modules/vitest/dist/cli.js --run test/syntax-highlight.test.ts` passes. - Before, `getLanguageFromPath("a.dart")` (and `.nix`, `.groovy`, `build.gradle`) returned `undefined` from the built dist. After, they return `dart`, `nix`, `groovy`, and `groovy`. - `npm run check` reports 6 type errors in `packages/ai/test` (model ID types). Main without this change has the same 6 errors. Fixes #11643 Requested by @badlogic Co-authored-by: triagent --- .../src/modes/interactive/theme/theme.ts | 4 ++++ .../coding-agent/test/syntax-highlight.test.ts | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/coding-agent/src/modes/interactive/theme/theme.ts b/packages/coding-agent/src/modes/interactive/theme/theme.ts index 922b23d9f..8b43443f3 100644 --- a/packages/coding-agent/src/modes/interactive/theme/theme.ts +++ b/packages/coding-agent/src/modes/interactive/theme/theme.ts @@ -1008,6 +1008,10 @@ export function getLanguageFromPath(filePath: string): string | undefined { java: "java", kt: "kotlin", swift: "swift", + dart: "dart", + groovy: "groovy", + gradle: "groovy", + nix: "nix", c: "c", h: "c", cpp: "cpp", diff --git a/packages/coding-agent/test/syntax-highlight.test.ts b/packages/coding-agent/test/syntax-highlight.test.ts index 17fe3b2e4..f4ff51c2b 100644 --- a/packages/coding-agent/test/syntax-highlight.test.ts +++ b/packages/coding-agent/test/syntax-highlight.test.ts @@ -1,6 +1,12 @@ import { resetCapabilitiesCache, setCapabilities } from "@earendil-works/pi-tui"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; -import { getMarkdownTheme, highlightCode, initTheme, theme } from "../src/modes/interactive/theme/theme.ts"; +import { + getLanguageFromPath, + getMarkdownTheme, + highlightCode, + initTheme, + theme, +} from "../src/modes/interactive/theme/theme.ts"; import { highlight, loadAllHighlightLanguages, @@ -41,6 +47,14 @@ describe("syntax highlight renderer", () => { expect(supportsLanguage("ada")).toBe(true); }); + it("maps file extensions of eagerly loaded languages to their language", () => { + expect(getLanguageFromPath("lib/main.dart")).toBe("dart"); + expect(getLanguageFromPath("flake.nix")).toBe("nix"); + expect(getLanguageFromPath("script.groovy")).toBe("groovy"); + expect(getLanguageFromPath("build.gradle")).toBe("groovy"); + expect(getLanguageFromPath("src/Main.kt")).toBe("kotlin"); + }); + it("renders highlighted spans with the provided theme", () => { const rendered = renderHighlightedHtml('const value', { keyword: (text) => `[keyword:${text}]`,