mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-04 09:49:50 +00:00
refactor(tui): generate syntax from V2 theme (#38397)
This commit is contained in:
parent
a817fe5e6c
commit
d86f732df3
2 changed files with 95 additions and 4 deletions
|
|
@ -4,10 +4,8 @@ import {
|
|||
DEFAULT_THEMES,
|
||||
addTheme,
|
||||
allThemes,
|
||||
generateSyntax,
|
||||
hasTheme,
|
||||
isTheme,
|
||||
resolveTheme,
|
||||
selectedForeground,
|
||||
setCustomThemes,
|
||||
setSystemTheme,
|
||||
|
|
@ -16,6 +14,7 @@ import {
|
|||
type Theme,
|
||||
type ThemeJson,
|
||||
} from "../theme"
|
||||
import { generateSyntax } from "../theme/v2/syntax"
|
||||
import { generateSystem, terminalMode } from "../theme/system"
|
||||
import { discoverThemes, themeDirectories } from "../theme/discovery"
|
||||
import { createComponentTheme, type ComponentTheme } from "../theme/v2/component"
|
||||
|
|
@ -279,7 +278,6 @@ const themeContext = createSimpleContext({
|
|||
if (supported.includes(store.mode)) return store.mode
|
||||
return supported[0] ?? store.mode
|
||||
}
|
||||
const legacySyntaxTheme = createMemo(() => resolveTheme(source(), mode()))
|
||||
const valuesV2 = createMemo(() => resolveThemeFile(file(), mode(), sourceName()))
|
||||
valuesV2()
|
||||
themePerformance.set("Init", `${(performance.now() - initStarted).toFixed(2)} ms`)
|
||||
|
|
@ -299,7 +297,7 @@ const themeContext = createSimpleContext({
|
|||
|
||||
createEffect(() => renderer.setBackgroundColor(valuesV2().background.default))
|
||||
|
||||
const syntax = createSyntaxStyleMemo(() => generateSyntax(legacySyntaxTheme()))
|
||||
const syntax = createSyntaxStyleMemo(() => generateSyntax(valuesV2(), mode()))
|
||||
function contextual(context: ContextName) {
|
||||
return contextualServices[context]
|
||||
}
|
||||
|
|
|
|||
93
packages/tui/src/theme/v2/syntax.ts
Normal file
93
packages/tui/src/theme/v2/syntax.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import { SyntaxStyle, type RGBA, type ThemeTokenStyle } from "@opentui/core"
|
||||
import type { Mode, ResolvedThemeView } from "./index"
|
||||
|
||||
export function generateSyntax(theme: ResolvedThemeView, mode: Mode) {
|
||||
const step = mode === "light" ? 800 : 200
|
||||
const syntax = theme.syntax
|
||||
const markdown = theme.markdown
|
||||
const feedback = theme.text.feedback
|
||||
|
||||
return SyntaxStyle.fromTheme([
|
||||
rule(["default"], theme.text.default),
|
||||
rule(["prompt"], theme.hue.accent[step]),
|
||||
rule(["extmark.file"], feedback.warning.default, { bold: true }),
|
||||
rule(["extmark.agent"], theme.categorical[0][step], { bold: true }),
|
||||
// V1 migration preserves its selected/inverse foreground in this action state.
|
||||
rule(["extmark.paste"], theme.text.action.primary.focused, {
|
||||
background: feedback.warning.default,
|
||||
bold: true,
|
||||
}),
|
||||
rule(["comment", "comment.documentation"], syntax.comment, { italic: true }),
|
||||
rule(["string", "symbol", "character.special", "character"], syntax.string),
|
||||
rule(["number", "boolean", "constant", "float"], syntax.number),
|
||||
rule(["keyword.return", "keyword.conditional", "keyword.repeat", "keyword.coroutine"], syntax.keyword, {
|
||||
italic: true,
|
||||
}),
|
||||
rule(["keyword.type"], syntax.type, { bold: true, italic: true }),
|
||||
rule(["keyword.function", "function.method"], syntax.function),
|
||||
rule(["keyword"], syntax.keyword, { italic: true }),
|
||||
rule(["keyword.import", "string.escape", "string.regexp", "tag.attribute", "keyword.export"], syntax.keyword),
|
||||
rule(["operator", "keyword.operator", "punctuation.delimiter", "keyword.conditional.ternary"], syntax.operator),
|
||||
rule(
|
||||
["variable", "variable.parameter", "function.method.call", "function.call", "property", "parameter", "field"],
|
||||
syntax.variable,
|
||||
),
|
||||
rule(["variable.member", "function", "constructor"], syntax.function),
|
||||
rule(["type", "module", "class", "namespace"], syntax.type),
|
||||
rule(["type.definition"], syntax.type, { bold: true }),
|
||||
rule(["punctuation", "punctuation.bracket"], syntax.punctuation),
|
||||
rule(
|
||||
["variable.builtin", "type.builtin", "function.builtin", "module.builtin", "constant.builtin", "variable.super"],
|
||||
feedback.error.default,
|
||||
),
|
||||
rule(["keyword.directive", "keyword.modifier", "keyword.exception"], syntax.keyword, { italic: true }),
|
||||
rule(["punctuation.special", "tag.delimiter"], syntax.operator),
|
||||
rule(
|
||||
[
|
||||
"markup.heading",
|
||||
"markup.heading.2",
|
||||
"markup.heading.3",
|
||||
"markup.heading.4",
|
||||
"markup.heading.5",
|
||||
"markup.heading.6",
|
||||
],
|
||||
markdown.heading,
|
||||
{ bold: true },
|
||||
),
|
||||
rule(["markup.heading.1"], markdown.heading, { bold: true, underline: true }),
|
||||
rule(["markup.bold", "markup.strong"], markdown.strong, { bold: true }),
|
||||
rule(["markup.italic"], markdown.emphasis, { italic: true }),
|
||||
rule(["markup.list"], markdown.listItem),
|
||||
rule(["markup.quote"], markdown.blockQuote, { italic: true }),
|
||||
rule(["markup.raw", "markup.raw.block"], markdown.code),
|
||||
rule(["markup.raw.inline"], markdown.code, { background: theme.background.default }),
|
||||
rule(["markup.link", "markup.link.url", "string.special", "string.special.url"], markdown.link, {
|
||||
underline: true,
|
||||
}),
|
||||
rule(["markup.link.label"], markdown.linkText, { underline: true }),
|
||||
rule(["label"], markdown.linkText),
|
||||
rule(["spell", "nospell"], theme.text.default),
|
||||
rule(["markup.underline"], theme.text.default, { underline: true }),
|
||||
rule(["comment.error"], feedback.error.default, { italic: true, bold: true }),
|
||||
rule(["comment.warning"], feedback.warning.default, { italic: true, bold: true }),
|
||||
rule(["comment.todo", "comment.note"], feedback.info.default, { italic: true, bold: true }),
|
||||
rule(["attribute", "annotation"], feedback.warning.default),
|
||||
rule(["tag"], feedback.error.default),
|
||||
rule(["markup.strikethrough", "markup.list.unchecked", "debug"], theme.text.subdued),
|
||||
rule(["markup.list.checked"], feedback.success.default),
|
||||
rule(["diff.plus"], theme.diff.text.added, { background: theme.diff.background.added }),
|
||||
rule(["diff.minus"], theme.diff.text.removed, { background: theme.diff.background.removed }),
|
||||
rule(["diff.delta"], theme.diff.text.context, { background: theme.diff.background.context }),
|
||||
rule(["error"], feedback.error.default, { bold: true }),
|
||||
rule(["warning"], feedback.warning.default, { bold: true }),
|
||||
rule(["info"], feedback.info.default),
|
||||
])
|
||||
}
|
||||
|
||||
function rule(
|
||||
scope: string[],
|
||||
foreground: RGBA,
|
||||
style: Omit<ThemeTokenStyle["style"], "foreground"> = {},
|
||||
): ThemeTokenStyle {
|
||||
return { scope, style: { foreground, ...style } }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue