flip theme type ownership
This commit is contained in:
@@ -43,66 +43,12 @@ import { Global } from "@/global"
|
||||
import { Filesystem } from "@/util/filesystem"
|
||||
import { useTuiConfig } from "./tui-config"
|
||||
import { isRecord } from "@/util/record"
|
||||
import type { TuiThemeCurrent } from "@opencode-ai/plugin/tui"
|
||||
|
||||
type ThemeColors = {
|
||||
primary: RGBA
|
||||
secondary: RGBA
|
||||
accent: RGBA
|
||||
error: RGBA
|
||||
warning: RGBA
|
||||
success: RGBA
|
||||
info: RGBA
|
||||
text: RGBA
|
||||
textMuted: RGBA
|
||||
selectedListItemText: RGBA
|
||||
background: RGBA
|
||||
backgroundPanel: RGBA
|
||||
backgroundElement: RGBA
|
||||
backgroundMenu: RGBA
|
||||
border: RGBA
|
||||
borderActive: RGBA
|
||||
borderSubtle: RGBA
|
||||
diffAdded: RGBA
|
||||
diffRemoved: RGBA
|
||||
diffContext: RGBA
|
||||
diffHunkHeader: RGBA
|
||||
diffHighlightAdded: RGBA
|
||||
diffHighlightRemoved: RGBA
|
||||
diffAddedBg: RGBA
|
||||
diffRemovedBg: RGBA
|
||||
diffContextBg: RGBA
|
||||
diffLineNumber: RGBA
|
||||
diffAddedLineNumberBg: RGBA
|
||||
diffRemovedLineNumberBg: RGBA
|
||||
markdownText: RGBA
|
||||
markdownHeading: RGBA
|
||||
markdownLink: RGBA
|
||||
markdownLinkText: RGBA
|
||||
markdownCode: RGBA
|
||||
markdownBlockQuote: RGBA
|
||||
markdownEmph: RGBA
|
||||
markdownStrong: RGBA
|
||||
markdownHorizontalRule: RGBA
|
||||
markdownListItem: RGBA
|
||||
markdownListEnumeration: RGBA
|
||||
markdownImage: RGBA
|
||||
markdownImageText: RGBA
|
||||
markdownCodeBlock: RGBA
|
||||
syntaxComment: RGBA
|
||||
syntaxKeyword: RGBA
|
||||
syntaxFunction: RGBA
|
||||
syntaxVariable: RGBA
|
||||
syntaxString: RGBA
|
||||
syntaxNumber: RGBA
|
||||
syntaxType: RGBA
|
||||
syntaxOperator: RGBA
|
||||
syntaxPunctuation: RGBA
|
||||
}
|
||||
|
||||
type Theme = ThemeColors & {
|
||||
type Theme = TuiThemeCurrent & {
|
||||
_hasSelectedListItemText: boolean
|
||||
thinkingOpacity: number
|
||||
}
|
||||
type ThemeColor = Exclude<keyof TuiThemeCurrent, "thinkingOpacity">
|
||||
|
||||
export function selectedForeground(theme: Theme, bg?: RGBA): RGBA {
|
||||
// If theme explicitly defines selectedListItemText, use it
|
||||
@@ -132,7 +78,7 @@ type ColorValue = HexColor | RefName | Variant | RGBA
|
||||
export type ThemeJson = {
|
||||
$schema?: string
|
||||
defs?: Record<string, HexColor | RefName>
|
||||
theme: Omit<Record<keyof ThemeColors, ColorValue>, "selectedListItemText" | "backgroundMenu"> & {
|
||||
theme: Omit<Record<ThemeColor, ColorValue>, "selectedListItemText" | "backgroundMenu"> & {
|
||||
selectedListItemText?: ColorValue
|
||||
backgroundMenu?: ColorValue
|
||||
thinkingOpacity?: number
|
||||
@@ -250,7 +196,7 @@ export function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
|
||||
throw new Error(`Circular color reference: ${[...chain, c].join(" -> ")}`)
|
||||
}
|
||||
|
||||
const next = defs[c] ?? theme.theme[c as keyof ThemeColors]
|
||||
const next = defs[c] ?? theme.theme[c as ThemeColor]
|
||||
if (next === undefined) {
|
||||
throw new Error(`Color reference "${c}" not found in defs or theme`)
|
||||
}
|
||||
@@ -268,7 +214,7 @@ export function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
|
||||
.map(([key, value]) => {
|
||||
return [key, resolveColor(value as ColorValue)]
|
||||
}),
|
||||
) as Partial<ThemeColors>
|
||||
) as Partial<Record<ThemeColor, RGBA>>
|
||||
|
||||
// Handle selectedListItemText separately since it's optional
|
||||
const hasSelectedListItemText = theme.theme.selectedListItemText !== undefined
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
import type { CliRenderer } from "@opentui/core"
|
||||
import { RGBA, type CliRenderer } from "@opentui/core"
|
||||
import { createPluginKeybind } from "../../src/cli/cmd/tui/context/plugin-keybinds"
|
||||
import type { HostPluginApi } from "../../src/cli/cmd/tui/plugin/slots"
|
||||
|
||||
@@ -12,6 +12,74 @@ type Count = {
|
||||
command_drop: number
|
||||
}
|
||||
|
||||
function themeCurrent(): HostPluginApi["theme"]["current"] {
|
||||
const a = RGBA.fromInts(0, 120, 240)
|
||||
const b = RGBA.fromInts(120, 120, 120)
|
||||
const c = RGBA.fromInts(230, 230, 230)
|
||||
const d = RGBA.fromInts(120, 30, 30)
|
||||
const e = RGBA.fromInts(140, 100, 40)
|
||||
const f = RGBA.fromInts(20, 140, 80)
|
||||
const g = RGBA.fromInts(20, 80, 160)
|
||||
const h = RGBA.fromInts(40, 40, 40)
|
||||
const i = RGBA.fromInts(60, 60, 60)
|
||||
const j = RGBA.fromInts(80, 80, 80)
|
||||
return {
|
||||
primary: a,
|
||||
secondary: b,
|
||||
accent: a,
|
||||
error: d,
|
||||
warning: e,
|
||||
success: f,
|
||||
info: g,
|
||||
text: c,
|
||||
textMuted: b,
|
||||
selectedListItemText: h,
|
||||
background: h,
|
||||
backgroundPanel: h,
|
||||
backgroundElement: i,
|
||||
backgroundMenu: i,
|
||||
border: j,
|
||||
borderActive: c,
|
||||
borderSubtle: i,
|
||||
diffAdded: f,
|
||||
diffRemoved: d,
|
||||
diffContext: b,
|
||||
diffHunkHeader: b,
|
||||
diffHighlightAdded: f,
|
||||
diffHighlightRemoved: d,
|
||||
diffAddedBg: h,
|
||||
diffRemovedBg: h,
|
||||
diffContextBg: h,
|
||||
diffLineNumber: b,
|
||||
diffAddedLineNumberBg: h,
|
||||
diffRemovedLineNumberBg: h,
|
||||
markdownText: c,
|
||||
markdownHeading: c,
|
||||
markdownLink: a,
|
||||
markdownLinkText: g,
|
||||
markdownCode: f,
|
||||
markdownBlockQuote: e,
|
||||
markdownEmph: e,
|
||||
markdownStrong: c,
|
||||
markdownHorizontalRule: b,
|
||||
markdownListItem: a,
|
||||
markdownListEnumeration: g,
|
||||
markdownImage: a,
|
||||
markdownImageText: g,
|
||||
markdownCodeBlock: c,
|
||||
syntaxComment: b,
|
||||
syntaxKeyword: a,
|
||||
syntaxFunction: g,
|
||||
syntaxVariable: c,
|
||||
syntaxString: f,
|
||||
syntaxNumber: e,
|
||||
syntaxType: a,
|
||||
syntaxOperator: a,
|
||||
syntaxPunctuation: c,
|
||||
thinkingOpacity: 0.6,
|
||||
}
|
||||
}
|
||||
|
||||
type Opts = {
|
||||
client?: HostPluginApi["client"]
|
||||
renderer?: HostPluginApi["renderer"]
|
||||
@@ -185,18 +253,7 @@ export function createTuiPluginApi(opts: Opts = {}): HostPluginApi {
|
||||
},
|
||||
theme: {
|
||||
get current() {
|
||||
return (
|
||||
opts.theme?.current ?? {
|
||||
text: "#ffffff",
|
||||
textMuted: "#999999",
|
||||
success: "#00ff00",
|
||||
error: "#ff0000",
|
||||
warning: "#ffff00",
|
||||
backgroundElement: "#111111",
|
||||
diffAdded: "#00ff00",
|
||||
diffRemoved: "#ff0000",
|
||||
}
|
||||
)
|
||||
return opts.theme?.current ?? themeCurrent()
|
||||
},
|
||||
get selected() {
|
||||
return selected
|
||||
|
||||
@@ -136,15 +136,59 @@ export type TuiToast = {
|
||||
}
|
||||
|
||||
export type TuiThemeCurrent = {
|
||||
readonly text: RGBA | string
|
||||
readonly textMuted: RGBA | string
|
||||
readonly success: RGBA | string
|
||||
readonly error: RGBA | string
|
||||
readonly warning: RGBA | string
|
||||
readonly backgroundElement: RGBA | string
|
||||
readonly diffAdded: RGBA | string
|
||||
readonly diffRemoved: RGBA | string
|
||||
readonly [key: string]: RGBA | string | number | boolean
|
||||
readonly primary: RGBA
|
||||
readonly secondary: RGBA
|
||||
readonly accent: RGBA
|
||||
readonly error: RGBA
|
||||
readonly warning: RGBA
|
||||
readonly success: RGBA
|
||||
readonly info: RGBA
|
||||
readonly text: RGBA
|
||||
readonly textMuted: RGBA
|
||||
readonly selectedListItemText: RGBA
|
||||
readonly background: RGBA
|
||||
readonly backgroundPanel: RGBA
|
||||
readonly backgroundElement: RGBA
|
||||
readonly backgroundMenu: RGBA
|
||||
readonly border: RGBA
|
||||
readonly borderActive: RGBA
|
||||
readonly borderSubtle: RGBA
|
||||
readonly diffAdded: RGBA
|
||||
readonly diffRemoved: RGBA
|
||||
readonly diffContext: RGBA
|
||||
readonly diffHunkHeader: RGBA
|
||||
readonly diffHighlightAdded: RGBA
|
||||
readonly diffHighlightRemoved: RGBA
|
||||
readonly diffAddedBg: RGBA
|
||||
readonly diffRemovedBg: RGBA
|
||||
readonly diffContextBg: RGBA
|
||||
readonly diffLineNumber: RGBA
|
||||
readonly diffAddedLineNumberBg: RGBA
|
||||
readonly diffRemovedLineNumberBg: RGBA
|
||||
readonly markdownText: RGBA
|
||||
readonly markdownHeading: RGBA
|
||||
readonly markdownLink: RGBA
|
||||
readonly markdownLinkText: RGBA
|
||||
readonly markdownCode: RGBA
|
||||
readonly markdownBlockQuote: RGBA
|
||||
readonly markdownEmph: RGBA
|
||||
readonly markdownStrong: RGBA
|
||||
readonly markdownHorizontalRule: RGBA
|
||||
readonly markdownListItem: RGBA
|
||||
readonly markdownListEnumeration: RGBA
|
||||
readonly markdownImage: RGBA
|
||||
readonly markdownImageText: RGBA
|
||||
readonly markdownCodeBlock: RGBA
|
||||
readonly syntaxComment: RGBA
|
||||
readonly syntaxKeyword: RGBA
|
||||
readonly syntaxFunction: RGBA
|
||||
readonly syntaxVariable: RGBA
|
||||
readonly syntaxString: RGBA
|
||||
readonly syntaxNumber: RGBA
|
||||
readonly syntaxType: RGBA
|
||||
readonly syntaxOperator: RGBA
|
||||
readonly syntaxPunctuation: RGBA
|
||||
readonly thinkingOpacity: number
|
||||
}
|
||||
|
||||
export type TuiTheme = {
|
||||
|
||||
Reference in New Issue
Block a user