diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx index a17b1353379..1a774d4a883 100644 --- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx @@ -93,6 +93,9 @@ type ThemeColors = { syntaxType: RGBA syntaxOperator: RGBA syntaxPunctuation: RGBA + syntaxTag: RGBA + syntaxAttribute: RGBA + syntaxTagDelimiter: RGBA } type Theme = ThemeColors & { @@ -127,9 +130,15 @@ type ColorValue = HexColor | RefName | Variant | RGBA type ThemeJson = { $schema?: string defs?: Record - theme: Omit, "selectedListItemText" | "backgroundMenu"> & { + theme: Omit< + Record, + "selectedListItemText" | "backgroundMenu" | "syntaxTag" | "syntaxAttribute" | "syntaxTagDelimiter" + > & { selectedListItemText?: ColorValue backgroundMenu?: ColorValue + syntaxTag?: ColorValue + syntaxAttribute?: ColorValue + syntaxTagDelimiter?: ColorValue thinkingOpacity?: number } } @@ -193,7 +202,15 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") { const resolved = Object.fromEntries( Object.entries(theme.theme) - .filter(([key]) => key !== "selectedListItemText" && key !== "backgroundMenu" && key !== "thinkingOpacity") + .filter( + ([key]) => + key !== "selectedListItemText" && + key !== "backgroundMenu" && + key !== "thinkingOpacity" && + key !== "syntaxTag" && + key !== "syntaxAttribute" && + key !== "syntaxTagDelimiter", + ) .map(([key, value]) => { return [key, resolveColor(value as ColorValue)] }), @@ -216,6 +233,24 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") { resolved.backgroundMenu = resolved.backgroundElement } + if (theme.theme.syntaxTag !== undefined) { + resolved.syntaxTag = resolveColor(theme.theme.syntaxTag) + } else { + resolved.syntaxTag = resolved.error + } + + if (theme.theme.syntaxAttribute !== undefined) { + resolved.syntaxAttribute = resolveColor(theme.theme.syntaxAttribute) + } else { + resolved.syntaxAttribute = resolved.syntaxKeyword + } + + if (theme.theme.syntaxTagDelimiter !== undefined) { + resolved.syntaxTagDelimiter = resolveColor(theme.theme.syntaxTagDelimiter) + } else { + resolved.syntaxTagDelimiter = resolved.syntaxOperator + } + // Handle thinkingOpacity - optional with default of 0.6 const thinkingOpacity = theme.theme.thinkingOpacity ?? 0.6 @@ -487,6 +522,9 @@ function generateSystem(colors: TerminalColors, mode: "dark" | "light"): ThemeJs syntaxType: ansiColors.cyan, syntaxOperator: ansiColors.cyan, syntaxPunctuation: fg, + syntaxTag: ansiColors.red, + syntaxAttribute: ansiColors.magenta, + syntaxTagDelimiter: ansiColors.cyan, }, } } @@ -1018,19 +1056,19 @@ function getSyntaxRules(theme: Theme) { { scope: ["tag"], style: { - foreground: theme.error, + foreground: theme.syntaxTag, }, }, { scope: ["tag.attribute"], style: { - foreground: theme.syntaxKeyword, + foreground: theme.syntaxAttribute, }, }, { scope: ["tag.delimiter"], style: { - foreground: theme.syntaxOperator, + foreground: theme.syntaxTagDelimiter, }, }, { diff --git a/packages/opencode/src/cli/cmd/tui/context/theme/opencode.json b/packages/opencode/src/cli/cmd/tui/context/theme/opencode.json index 8f585a45091..f4203066d39 100644 --- a/packages/opencode/src/cli/cmd/tui/context/theme/opencode.json +++ b/packages/opencode/src/cli/cmd/tui/context/theme/opencode.json @@ -240,6 +240,18 @@ "syntaxPunctuation": { "dark": "darkStep12", "light": "lightStep12" + }, + "syntaxTag": { + "dark": "darkRed", + "light": "lightRed" + }, + "syntaxAttribute": { + "dark": "darkAccent", + "light": "lightAccent" + }, + "syntaxTagDelimiter": { + "dark": "darkCyan", + "light": "lightCyan" } } } diff --git a/packages/web/public/theme.json b/packages/web/public/theme.json index 7c80776344f..c1103f28de3 100644 --- a/packages/web/public/theme.json +++ b/packages/web/public/theme.json @@ -87,7 +87,10 @@ "syntaxNumber": { "$ref": "#/definitions/colorValue" }, "syntaxType": { "$ref": "#/definitions/colorValue" }, "syntaxOperator": { "$ref": "#/definitions/colorValue" }, - "syntaxPunctuation": { "$ref": "#/definitions/colorValue" } + "syntaxPunctuation": { "$ref": "#/definitions/colorValue" }, + "syntaxTag": { "$ref": "#/definitions/colorValue" }, + "syntaxAttribute": { "$ref": "#/definitions/colorValue" }, + "syntaxTagDelimiter": { "$ref": "#/definitions/colorValue" } }, "required": ["primary", "secondary", "accent", "text", "textMuted", "background"], "additionalProperties": false