659 lines
14 KiB
TypeScript
659 lines
14 KiB
TypeScript
|
|
import { SyntaxStyle, RGBA } from "@opentui/core"
|
||
|
|
import { createMemo, createSignal, createEffect } from "solid-js"
|
||
|
|
import { useSync } from "@tui/context/sync"
|
||
|
|
import { createSimpleContext } from "./helper"
|
||
|
|
import aura from "../../../../../../tui/internal/theme/themes/aura.json" with { type: "json" }
|
||
|
|
import ayu from "../../../../../../tui/internal/theme/themes/ayu.json" with { type: "json" }
|
||
|
|
import catppuccin from "../../../../../../tui/internal/theme/themes/catppuccin.json" with { type: "json" }
|
||
|
|
import cobalt2 from "../../../../../../tui/internal/theme/themes/cobalt2.json" with { type: "json" }
|
||
|
|
import dracula from "../../../../../../tui/internal/theme/themes/dracula.json" with { type: "json" }
|
||
|
|
import everforest from "../../../../../../tui/internal/theme/themes/everforest.json" with { type: "json" }
|
||
|
|
import github from "../../../../../../tui/internal/theme/themes/github.json" with { type: "json" }
|
||
|
|
import gruvbox from "../../../../../../tui/internal/theme/themes/gruvbox.json" with { type: "json" }
|
||
|
|
import kanagawa from "../../../../../../tui/internal/theme/themes/kanagawa.json" with { type: "json" }
|
||
|
|
import material from "../../../../../../tui/internal/theme/themes/material.json" with { type: "json" }
|
||
|
|
import matrix from "../../../../../../tui/internal/theme/themes/matrix.json" with { type: "json" }
|
||
|
|
import monokai from "../../../../../../tui/internal/theme/themes/monokai.json" with { type: "json" }
|
||
|
|
import nord from "../../../../../../tui/internal/theme/themes/nord.json" with { type: "json" }
|
||
|
|
import onedark from "../../../../../../tui/internal/theme/themes/one-dark.json" with { type: "json" }
|
||
|
|
import opencode from "../../../../../../tui/internal/theme/themes/opencode.json" with { type: "json" }
|
||
|
|
import palenight from "../../../../../../tui/internal/theme/themes/palenight.json" with { type: "json" }
|
||
|
|
import rosepine from "../../../../../../tui/internal/theme/themes/rosepine.json" with { type: "json" }
|
||
|
|
import solarized from "../../../../../../tui/internal/theme/themes/solarized.json" with { type: "json" }
|
||
|
|
import synthwave84 from "../../../../../../tui/internal/theme/themes/synthwave84.json" with { type: "json" }
|
||
|
|
import tokyonight from "../../../../../../tui/internal/theme/themes/tokyonight.json" with { type: "json" }
|
||
|
|
import vesper from "../../../../../../tui/internal/theme/themes/vesper.json" with { type: "json" }
|
||
|
|
import zenburn from "../../../../../../tui/internal/theme/themes/zenburn.json" with { type: "json" }
|
||
|
|
import { iife } from "@/util/iife"
|
||
|
|
import { createStore, reconcile } from "solid-js/store"
|
||
|
|
|
||
|
|
type Theme = {
|
||
|
|
primary: RGBA
|
||
|
|
secondary: RGBA
|
||
|
|
accent: RGBA
|
||
|
|
error: RGBA
|
||
|
|
warning: RGBA
|
||
|
|
success: RGBA
|
||
|
|
info: RGBA
|
||
|
|
text: RGBA
|
||
|
|
textMuted: RGBA
|
||
|
|
background: RGBA
|
||
|
|
backgroundPanel: RGBA
|
||
|
|
backgroundElement: 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
|
||
|
|
}
|
||
|
|
|
||
|
|
type HexColor = `#${string}`
|
||
|
|
type RefName = string
|
||
|
|
type ColorModeObj = {
|
||
|
|
dark: HexColor | RefName
|
||
|
|
light: HexColor | RefName
|
||
|
|
}
|
||
|
|
type ColorValue = HexColor | RefName | ColorModeObj
|
||
|
|
type ThemeJson = {
|
||
|
|
$schema?: string
|
||
|
|
defs?: Record<string, HexColor | RefName>
|
||
|
|
theme: Record<keyof Theme, ColorValue>
|
||
|
|
}
|
||
|
|
|
||
|
|
export const THEMES = {
|
||
|
|
aura: resolveTheme(aura),
|
||
|
|
ayu: resolveTheme(ayu),
|
||
|
|
catppuccin: resolveTheme(catppuccin),
|
||
|
|
cobalt2: resolveTheme(cobalt2),
|
||
|
|
dracula: resolveTheme(dracula),
|
||
|
|
everforest: resolveTheme(everforest),
|
||
|
|
github: resolveTheme(github),
|
||
|
|
gruvbox: resolveTheme(gruvbox),
|
||
|
|
kanagawa: resolveTheme(kanagawa),
|
||
|
|
material: resolveTheme(material),
|
||
|
|
matrix: resolveTheme(matrix),
|
||
|
|
monokai: resolveTheme(monokai),
|
||
|
|
nord: resolveTheme(nord),
|
||
|
|
["one-dark"]: resolveTheme(onedark),
|
||
|
|
opencode: resolveTheme(opencode),
|
||
|
|
palenight: resolveTheme(palenight),
|
||
|
|
rosepine: resolveTheme(rosepine),
|
||
|
|
solarized: resolveTheme(solarized),
|
||
|
|
synthwave84: resolveTheme(synthwave84),
|
||
|
|
tokyonight: resolveTheme(tokyonight),
|
||
|
|
vesper: resolveTheme(vesper),
|
||
|
|
zenburn: resolveTheme(zenburn),
|
||
|
|
}
|
||
|
|
|
||
|
|
function resolveTheme(theme: ThemeJson) {
|
||
|
|
const defs = theme.defs ?? {}
|
||
|
|
function resolveColor(c: ColorValue): RGBA {
|
||
|
|
if (typeof c === "string") return c.startsWith("#") ? RGBA.fromHex(c) : resolveColor(defs[c])
|
||
|
|
// TODO: support light theme when opentui has the equivalent of lipgloss.AdaptiveColor
|
||
|
|
return resolveColor(c.dark)
|
||
|
|
}
|
||
|
|
return Object.fromEntries(
|
||
|
|
Object.entries(theme.theme).map(([key, value]) => {
|
||
|
|
return [key, resolveColor(value)]
|
||
|
|
}),
|
||
|
|
) as Theme
|
||
|
|
}
|
||
|
|
|
||
|
|
const syntaxThemeDark = [
|
||
|
|
{
|
||
|
|
scope: ["prompt"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7dcfff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["extmark.file"],
|
||
|
|
style: {
|
||
|
|
foreground: "#ff9e64",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["extmark.agent"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["extmark.paste"],
|
||
|
|
style: {
|
||
|
|
foreground: "#1a1b26",
|
||
|
|
background: "#ff9e64",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["comment"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["comment.documentation"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["string", "symbol"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["number", "boolean"],
|
||
|
|
style: {
|
||
|
|
foreground: "#ff9e64",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["character.special"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.return", "keyword.conditional", "keyword.repeat", "keyword.coroutine"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.type"],
|
||
|
|
style: {
|
||
|
|
foreground: "#2ac3de",
|
||
|
|
bold: true,
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.function", "function.method"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.import"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["operator", "keyword.operator", "punctuation.delimiter"],
|
||
|
|
style: {
|
||
|
|
foreground: "#89ddff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.conditional.ternary"],
|
||
|
|
style: {
|
||
|
|
foreground: "#89ddff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["variable", "variable.parameter", "function.method.call", "function.call"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7dcfff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["variable.member", "function", "constructor"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7aa2f7",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["type", "module"],
|
||
|
|
style: {
|
||
|
|
foreground: "#2ac3de",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["constant"],
|
||
|
|
style: {
|
||
|
|
foreground: "#ff9e64",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["property"],
|
||
|
|
style: {
|
||
|
|
foreground: "#73daca",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["class"],
|
||
|
|
style: {
|
||
|
|
foreground: "#2ac3de",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["parameter"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e0af68",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["punctuation", "punctuation.bracket"],
|
||
|
|
style: {
|
||
|
|
foreground: "#89ddff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: [
|
||
|
|
"variable.builtin",
|
||
|
|
"type.builtin",
|
||
|
|
"function.builtin",
|
||
|
|
"module.builtin",
|
||
|
|
"constant.builtin",
|
||
|
|
],
|
||
|
|
style: {
|
||
|
|
foreground: "#f7768e",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["variable.super"],
|
||
|
|
style: {
|
||
|
|
foreground: "#f7768e",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["string.escape", "string.regexp"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.directive"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["punctuation.special"],
|
||
|
|
style: {
|
||
|
|
foreground: "#89ddff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.modifier"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.exception"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
// Markdown specific styles
|
||
|
|
{
|
||
|
|
scope: ["markup.heading"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7aa2f7",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.heading.1"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.heading.2"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7aa2f7",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.heading.3"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7dcfff",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.heading.4"],
|
||
|
|
style: {
|
||
|
|
foreground: "#73daca",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.heading.5"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.heading.6"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.bold", "markup.strong"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e6edf3",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.italic"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e6edf3",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.list"],
|
||
|
|
style: {
|
||
|
|
foreground: "#ff9e64",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.quote"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
italic: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.raw", "markup.raw.block"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.raw.inline"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
background: "#1a1b26",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.link"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7aa2f7",
|
||
|
|
underline: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.link.label"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7dcfff",
|
||
|
|
underline: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.link.url"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7aa2f7",
|
||
|
|
underline: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["label"],
|
||
|
|
style: {
|
||
|
|
foreground: "#73daca",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["spell", "nospell"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e6edf3",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["conceal"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
// Additional common highlight groups
|
||
|
|
{
|
||
|
|
scope: ["string.special", "string.special.url"],
|
||
|
|
style: {
|
||
|
|
foreground: "#73daca",
|
||
|
|
underline: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["character"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["float"],
|
||
|
|
style: {
|
||
|
|
foreground: "#ff9e64",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["comment.error"],
|
||
|
|
style: {
|
||
|
|
foreground: "#f7768e",
|
||
|
|
italic: true,
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["comment.warning"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e0af68",
|
||
|
|
italic: true,
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["comment.todo", "comment.note"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7aa2f7",
|
||
|
|
italic: true,
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["namespace"],
|
||
|
|
style: {
|
||
|
|
foreground: "#2ac3de",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["field"],
|
||
|
|
style: {
|
||
|
|
foreground: "#73daca",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["type.definition"],
|
||
|
|
style: {
|
||
|
|
foreground: "#2ac3de",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["keyword.export"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["attribute", "annotation"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e0af68",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["tag"],
|
||
|
|
style: {
|
||
|
|
foreground: "#f7768e",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["tag.attribute"],
|
||
|
|
style: {
|
||
|
|
foreground: "#bb9af7",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["tag.delimiter"],
|
||
|
|
style: {
|
||
|
|
foreground: "#89ddff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.strikethrough"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.underline"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e6edf3",
|
||
|
|
underline: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.list.checked"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["markup.list.unchecked"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["diff.plus"],
|
||
|
|
style: {
|
||
|
|
foreground: "#9ece6a",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["diff.minus"],
|
||
|
|
style: {
|
||
|
|
foreground: "#f7768e",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["diff.delta"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7dcfff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["error"],
|
||
|
|
style: {
|
||
|
|
foreground: "#f7768e",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["warning"],
|
||
|
|
style: {
|
||
|
|
foreground: "#e0af68",
|
||
|
|
bold: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["info"],
|
||
|
|
style: {
|
||
|
|
foreground: "#7dcfff",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
{
|
||
|
|
scope: ["debug"],
|
||
|
|
style: {
|
||
|
|
foreground: "#565f89",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
export const SyntaxTheme = SyntaxStyle.fromTheme(syntaxThemeDark)
|
||
|
|
|
||
|
|
export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
||
|
|
name: "Theme",
|
||
|
|
init: () => {
|
||
|
|
const sync = useSync()
|
||
|
|
const [selectedTheme, setSelectedTheme] = createSignal<keyof typeof THEMES>("opencode")
|
||
|
|
const [theme, setTheme] = createStore({} as Theme)
|
||
|
|
createEffect(() => {
|
||
|
|
if (!sync.ready) return
|
||
|
|
setSelectedTheme(
|
||
|
|
iife(() => {
|
||
|
|
if (typeof sync.data.config.theme === "string" && sync.data.config.theme in THEMES) {
|
||
|
|
return sync.data.config.theme as keyof typeof THEMES
|
||
|
|
}
|
||
|
|
return "opencode"
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
})
|
||
|
|
|
||
|
|
createEffect(() => {
|
||
|
|
setTheme(reconcile(THEMES[selectedTheme()]))
|
||
|
|
})
|
||
|
|
|
||
|
|
return {
|
||
|
|
theme,
|
||
|
|
selectedTheme,
|
||
|
|
setSelectedTheme,
|
||
|
|
get ready() {
|
||
|
|
return sync.ready
|
||
|
|
},
|
||
|
|
}
|
||
|
|
},
|
||
|
|
})
|