@neurocode-ai/tui 1.18.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bunfig.toml +4 -0
- package/package.json +72 -0
- package/src/app.tsx +1134 -0
- package/src/attention.ts +260 -0
- package/src/audio.d.ts +9 -0
- package/src/audio.ts +53 -0
- package/src/clipboard.ts +124 -0
- package/src/component/bg-pulse-render.ts +436 -0
- package/src/component/bg-pulse.tsx +99 -0
- package/src/component/command-palette.tsx +79 -0
- package/src/component/dialog-agent.tsx +31 -0
- package/src/component/dialog-console-org.tsx +135 -0
- package/src/component/dialog-debug.tsx +90 -0
- package/src/component/dialog-mcp.tsx +85 -0
- package/src/component/dialog-model.tsx +197 -0
- package/src/component/dialog-move-session.tsx +353 -0
- package/src/component/dialog-provider.tsx +469 -0
- package/src/component/dialog-retry-action.tsx +160 -0
- package/src/component/dialog-session-delete-failed.tsx +99 -0
- package/src/component/dialog-session-list.tsx +364 -0
- package/src/component/dialog-session-rename.tsx +31 -0
- package/src/component/dialog-skill.tsx +70 -0
- package/src/component/dialog-stash.tsx +87 -0
- package/src/component/dialog-status.tsx +168 -0
- package/src/component/dialog-tag.tsx +47 -0
- package/src/component/dialog-theme-list.tsx +50 -0
- package/src/component/dialog-variant.tsx +39 -0
- package/src/component/dialog-workspace-create.tsx +308 -0
- package/src/component/dialog-workspace-file-changes.tsx +144 -0
- package/src/component/dialog-workspace-list.tsx +112 -0
- package/src/component/dialog-workspace-unavailable.tsx +69 -0
- package/src/component/error-component.tsx +240 -0
- package/src/component/logo.tsx +61 -0
- package/src/component/plugin-route-missing.tsx +14 -0
- package/src/component/prompt/autocomplete.tsx +781 -0
- package/src/component/prompt/cwd.ts +0 -0
- package/src/component/prompt/frecency.tsx +1 -0
- package/src/component/prompt/history.tsx +1 -0
- package/src/component/prompt/index.tsx +1713 -0
- package/src/component/prompt/local-attachment.ts +48 -0
- package/src/component/prompt/move.tsx +205 -0
- package/src/component/prompt/stash.tsx +1 -0
- package/src/component/prompt/workspace.tsx +137 -0
- package/src/component/register-spinner.ts +6 -0
- package/src/component/spinner.tsx +26 -0
- package/src/component/startup-loading.tsx +63 -0
- package/src/component/todo-item.tsx +32 -0
- package/src/component/use-connected.tsx +12 -0
- package/src/component/workspace-label.tsx +19 -0
- package/src/config/index.tsx +129 -0
- package/src/config/keybind.ts +471 -0
- package/src/context/args.tsx +16 -0
- package/src/context/clipboard.tsx +18 -0
- package/src/context/data.tsx +569 -0
- package/src/context/directory.ts +17 -0
- package/src/context/editor.ts +408 -0
- package/src/context/epilogue.tsx +6 -0
- package/src/context/event.ts +36 -0
- package/src/context/exit.tsx +8 -0
- package/src/context/helper.tsx +26 -0
- package/src/context/kv.tsx +66 -0
- package/src/context/local.tsx +542 -0
- package/src/context/location.tsx +14 -0
- package/src/context/path-format.tsx +24 -0
- package/src/context/permission.tsx +26 -0
- package/src/context/project.tsx +115 -0
- package/src/context/prompt.tsx +18 -0
- package/src/context/route.tsx +60 -0
- package/src/context/runtime.tsx +62 -0
- package/src/context/sdk.tsx +151 -0
- package/src/context/sync.tsx +666 -0
- package/src/context/theme.tsx +332 -0
- package/src/context/thinking.ts +67 -0
- package/src/editor-zed.ts +286 -0
- package/src/editor.ts +101 -0
- package/src/feature-plugins/builtins.ts +36 -0
- package/src/feature-plugins/home/footer.tsx +100 -0
- package/src/feature-plugins/home/tips-view.tsx +287 -0
- package/src/feature-plugins/home/tips.tsx +59 -0
- package/src/feature-plugins/sidebar/context.tsx +65 -0
- package/src/feature-plugins/sidebar/files.tsx +70 -0
- package/src/feature-plugins/sidebar/footer.tsx +98 -0
- package/src/feature-plugins/sidebar/lsp.tsx +65 -0
- package/src/feature-plugins/sidebar/mcp.tsx +97 -0
- package/src/feature-plugins/sidebar/todo.tsx +49 -0
- package/src/feature-plugins/system/diff-viewer-file-tree-utils.ts +232 -0
- package/src/feature-plugins/system/diff-viewer-file-tree.tsx +162 -0
- package/src/feature-plugins/system/diff-viewer-ui.tsx +103 -0
- package/src/feature-plugins/system/diff-viewer.tsx +1077 -0
- package/src/feature-plugins/system/notifications.ts +94 -0
- package/src/feature-plugins/system/plugins.tsx +269 -0
- package/src/feature-plugins/system/which-key.tsx +608 -0
- package/src/index.tsx +1 -0
- package/src/keymap.tsx +290 -0
- package/src/logo.ts +11 -0
- package/src/parsers-config.ts +386 -0
- package/src/plugin/adapters.tsx +355 -0
- package/src/plugin/api.ts +52 -0
- package/src/plugin/command-shim.ts +109 -0
- package/src/plugin/runtime.tsx +81 -0
- package/src/plugin/slots.tsx +65 -0
- package/src/prompt/display.ts +48 -0
- package/src/prompt/frecency.tsx +80 -0
- package/src/prompt/history.tsx +111 -0
- package/src/prompt/part.ts +29 -0
- package/src/prompt/stash.tsx +89 -0
- package/src/prompt/traits.ts +29 -0
- package/src/routes/home/session-destination.tsx +41 -0
- package/src/routes/home.tsx +95 -0
- package/src/routes/session/dialog-fork-from-timeline.tsx +76 -0
- package/src/routes/session/dialog-message.tsx +109 -0
- package/src/routes/session/dialog-subagent.tsx +26 -0
- package/src/routes/session/dialog-timeline.tsx +47 -0
- package/src/routes/session/footer.tsx +91 -0
- package/src/routes/session/index.tsx +2710 -0
- package/src/routes/session/permission.tsx +718 -0
- package/src/routes/session/question.tsx +514 -0
- package/src/routes/session/sidebar.tsx +103 -0
- package/src/routes/session/subagent-footer.tsx +132 -0
- package/src/runtime.tsx +9 -0
- package/src/terminal-win32.ts +130 -0
- package/src/theme/assets/aura.json +69 -0
- package/src/theme/assets/ayu.json +80 -0
- package/src/theme/assets/carbonfox.json +248 -0
- package/src/theme/assets/catppuccin-frappe.json +230 -0
- package/src/theme/assets/catppuccin-macchiato.json +230 -0
- package/src/theme/assets/catppuccin.json +112 -0
- package/src/theme/assets/cobalt2.json +225 -0
- package/src/theme/assets/cursor.json +249 -0
- package/src/theme/assets/dracula.json +219 -0
- package/src/theme/assets/everforest.json +241 -0
- package/src/theme/assets/flexoki.json +237 -0
- package/src/theme/assets/github.json +233 -0
- package/src/theme/assets/gruvbox.json +242 -0
- package/src/theme/assets/kanagawa.json +77 -0
- package/src/theme/assets/lucent-orng.json +234 -0
- package/src/theme/assets/material.json +235 -0
- package/src/theme/assets/matrix.json +77 -0
- package/src/theme/assets/mercury.json +252 -0
- package/src/theme/assets/monokai.json +221 -0
- package/src/theme/assets/nightowl.json +221 -0
- package/src/theme/assets/nord.json +223 -0
- package/src/theme/assets/one-dark.json +84 -0
- package/src/theme/assets/opencode.json +245 -0
- package/src/theme/assets/orng.json +249 -0
- package/src/theme/assets/osaka-jade.json +93 -0
- package/src/theme/assets/palenight.json +222 -0
- package/src/theme/assets/rosepine.json +234 -0
- package/src/theme/assets/solarized.json +223 -0
- package/src/theme/assets/synthwave84.json +226 -0
- package/src/theme/assets/tokyonight.json +243 -0
- package/src/theme/assets/vercel.json +245 -0
- package/src/theme/assets/vesper.json +218 -0
- package/src/theme/assets/zenburn.json +223 -0
- package/src/theme/index.ts +1089 -0
- package/src/ui/border.ts +21 -0
- package/src/ui/dialog-alert.tsx +66 -0
- package/src/ui/dialog-confirm.tsx +108 -0
- package/src/ui/dialog-export-options.tsx +217 -0
- package/src/ui/dialog-help.tsx +40 -0
- package/src/ui/dialog-prompt.tsx +126 -0
- package/src/ui/dialog-select.tsx +790 -0
- package/src/ui/dialog.tsx +231 -0
- package/src/ui/link.tsx +34 -0
- package/src/ui/spinner.ts +368 -0
- package/src/ui/toast.tsx +102 -0
- package/src/util/collapse-tool-output.ts +19 -0
- package/src/util/error.ts +182 -0
- package/src/util/filetype.ts +130 -0
- package/src/util/format.ts +20 -0
- package/src/util/layout.ts +25 -0
- package/src/util/locale.ts +86 -0
- package/src/util/model.ts +28 -0
- package/src/util/path.ts +12 -0
- package/src/util/persistence.ts +33 -0
- package/src/util/presentation.ts +38 -0
- package/src/util/provider-origin.ts +7 -0
- package/src/util/record.ts +3 -0
- package/src/util/renderer.ts +7 -0
- package/src/util/revert-diff.ts +18 -0
- package/src/util/scroll.ts +27 -0
- package/src/util/selection.ts +79 -0
- package/src/util/session.ts +3 -0
- package/src/util/signal.ts +51 -0
- package/src/util/system.ts +20 -0
- package/src/util/tool-display.ts +13 -0
- package/src/util/transcript.ts +112 -0
- package/sst-env.d.ts +10 -0
- package/test/app-lifecycle.test.tsx +128 -0
- package/test/cli/cmd/tui/dialog-workspace-create.test.ts +28 -0
- package/test/cli/cmd/tui/model-options.test.ts +32 -0
- package/test/cli/cmd/tui/notifications.test.ts +267 -0
- package/test/cli/cmd/tui/provider-options.test.ts +41 -0
- package/test/cli/cmd/tui/sync-fixture.tsx +70 -0
- package/test/cli/cmd/tui/sync-live-hydration.test.tsx +262 -0
- package/test/cli/cmd/tui/sync-undefined-messages.test.tsx +43 -0
- package/test/cli/cmd/tui/sync.test.tsx +65 -0
- package/test/cli/tui/__snapshots__/inline-tool-wrap-snapshot.test.tsx.snap +92 -0
- package/test/cli/tui/data.test.tsx +486 -0
- package/test/cli/tui/dialog-prompt.test.tsx +147 -0
- package/test/cli/tui/diff-viewer-file-tree.test.tsx +200 -0
- package/test/cli/tui/diff-viewer.test.tsx +268 -0
- package/test/cli/tui/inline-tool-wrap-snapshot.test.tsx +351 -0
- package/test/cli/tui/prompt-submit-race.test.ts +98 -0
- package/test/cli/tui/thinking.test.ts +36 -0
- package/test/cli/tui/use-event.test.tsx +148 -0
- package/test/clipboard.test.ts +19 -0
- package/test/component/dialog-session-list.test.ts +46 -0
- package/test/config.test.tsx +127 -0
- package/test/context/local.test.ts +22 -0
- package/test/editor.test.ts +32 -0
- package/test/feature-plugins/diff-viewer-file-tree-utils.test.ts +323 -0
- package/test/fixture/fixture.ts +13 -0
- package/test/fixture/tui-environment.tsx +32 -0
- package/test/fixture/tui-plugin.ts +36 -0
- package/test/fixture/tui-runtime.ts +12 -0
- package/test/fixture/tui-sdk.ts +109 -0
- package/test/index.test.tsx +6 -0
- package/test/keymap.test.tsx +141 -0
- package/test/plugin/runtime.test.ts +50 -0
- package/test/plugin/slots.test.tsx +38 -0
- package/test/prompt/display.test.ts +33 -0
- package/test/prompt/history.test.ts +39 -0
- package/test/prompt/jsonl.test.ts +24 -0
- package/test/prompt/local-attachment.test.ts +43 -0
- package/test/prompt/part.test.ts +53 -0
- package/test/prompt/persistence.test.ts +23 -0
- package/test/prompt/traits.test.ts +25 -0
- package/test/runtime.test.tsx +37 -0
- package/test/theme.test.ts +81 -0
- package/test/util/error.test.ts +49 -0
- package/test/util/filetype.test.ts +16 -0
- package/test/util/format.test.ts +59 -0
- package/test/util/model.test.ts +9 -0
- package/test/util/presentation.test.ts +8 -0
- package/test/util/renderer.test.ts +30 -0
- package/test/util/revert-diff.test.ts +35 -0
- package/test/util/session.test.ts +10 -0
- package/test/util/tool-display.test.ts +40 -0
- package/test/util/transcript.test.ts +421 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1,1089 @@
|
|
|
1
|
+
import { SyntaxStyle, RGBA, type TerminalColors } from "@opentui/core"
|
|
2
|
+
import aura from "./assets/aura.json" with { type: "json" }
|
|
3
|
+
import ayu from "./assets/ayu.json" with { type: "json" }
|
|
4
|
+
import carbonfox from "./assets/carbonfox.json" with { type: "json" }
|
|
5
|
+
import catppuccinFrappe from "./assets/catppuccin-frappe.json" with { type: "json" }
|
|
6
|
+
import catppuccinMacchiato from "./assets/catppuccin-macchiato.json" with { type: "json" }
|
|
7
|
+
import catppuccin from "./assets/catppuccin.json" with { type: "json" }
|
|
8
|
+
import cobalt2 from "./assets/cobalt2.json" with { type: "json" }
|
|
9
|
+
import cursor from "./assets/cursor.json" with { type: "json" }
|
|
10
|
+
import dracula from "./assets/dracula.json" with { type: "json" }
|
|
11
|
+
import everforest from "./assets/everforest.json" with { type: "json" }
|
|
12
|
+
import flexoki from "./assets/flexoki.json" with { type: "json" }
|
|
13
|
+
import github from "./assets/github.json" with { type: "json" }
|
|
14
|
+
import gruvbox from "./assets/gruvbox.json" with { type: "json" }
|
|
15
|
+
import kanagawa from "./assets/kanagawa.json" with { type: "json" }
|
|
16
|
+
import lucentOrng from "./assets/lucent-orng.json" with { type: "json" }
|
|
17
|
+
import material from "./assets/material.json" with { type: "json" }
|
|
18
|
+
import matrix from "./assets/matrix.json" with { type: "json" }
|
|
19
|
+
import mercury from "./assets/mercury.json" with { type: "json" }
|
|
20
|
+
import monokai from "./assets/monokai.json" with { type: "json" }
|
|
21
|
+
import nightowl from "./assets/nightowl.json" with { type: "json" }
|
|
22
|
+
import nord from "./assets/nord.json" with { type: "json" }
|
|
23
|
+
import onedark from "./assets/one-dark.json" with { type: "json" }
|
|
24
|
+
import opencode from "./assets/opencode.json" with { type: "json" }
|
|
25
|
+
import orng from "./assets/orng.json" with { type: "json" }
|
|
26
|
+
import osakaJade from "./assets/osaka-jade.json" with { type: "json" }
|
|
27
|
+
import palenight from "./assets/palenight.json" with { type: "json" }
|
|
28
|
+
import rosepine from "./assets/rosepine.json" with { type: "json" }
|
|
29
|
+
import solarized from "./assets/solarized.json" with { type: "json" }
|
|
30
|
+
import synthwave84 from "./assets/synthwave84.json" with { type: "json" }
|
|
31
|
+
import tokyonight from "./assets/tokyonight.json" with { type: "json" }
|
|
32
|
+
import vercel from "./assets/vercel.json" with { type: "json" }
|
|
33
|
+
import vesper from "./assets/vesper.json" with { type: "json" }
|
|
34
|
+
import zenburn from "./assets/zenburn.json" with { type: "json" }
|
|
35
|
+
|
|
36
|
+
export type Theme = {
|
|
37
|
+
readonly primary: RGBA
|
|
38
|
+
readonly secondary: RGBA
|
|
39
|
+
readonly accent: RGBA
|
|
40
|
+
readonly error: RGBA
|
|
41
|
+
readonly warning: RGBA
|
|
42
|
+
readonly success: RGBA
|
|
43
|
+
readonly info: RGBA
|
|
44
|
+
readonly text: RGBA
|
|
45
|
+
readonly textMuted: RGBA
|
|
46
|
+
readonly selectedListItemText: RGBA
|
|
47
|
+
readonly background: RGBA
|
|
48
|
+
readonly backgroundPanel: RGBA
|
|
49
|
+
readonly backgroundElement: RGBA
|
|
50
|
+
readonly backgroundMenu: RGBA
|
|
51
|
+
readonly border: RGBA
|
|
52
|
+
readonly borderActive: RGBA
|
|
53
|
+
readonly borderSubtle: RGBA
|
|
54
|
+
readonly diffAdded: RGBA
|
|
55
|
+
readonly diffRemoved: RGBA
|
|
56
|
+
readonly diffContext: RGBA
|
|
57
|
+
readonly diffHunkHeader: RGBA
|
|
58
|
+
readonly diffHighlightAdded: RGBA
|
|
59
|
+
readonly diffHighlightRemoved: RGBA
|
|
60
|
+
readonly diffAddedBg: RGBA
|
|
61
|
+
readonly diffRemovedBg: RGBA
|
|
62
|
+
readonly diffContextBg: RGBA
|
|
63
|
+
readonly diffLineNumber: RGBA
|
|
64
|
+
readonly diffAddedLineNumberBg: RGBA
|
|
65
|
+
readonly diffRemovedLineNumberBg: RGBA
|
|
66
|
+
readonly markdownText: RGBA
|
|
67
|
+
readonly markdownHeading: RGBA
|
|
68
|
+
readonly markdownLink: RGBA
|
|
69
|
+
readonly markdownLinkText: RGBA
|
|
70
|
+
readonly markdownCode: RGBA
|
|
71
|
+
readonly markdownBlockQuote: RGBA
|
|
72
|
+
readonly markdownEmph: RGBA
|
|
73
|
+
readonly markdownStrong: RGBA
|
|
74
|
+
readonly markdownHorizontalRule: RGBA
|
|
75
|
+
readonly markdownListItem: RGBA
|
|
76
|
+
readonly markdownListEnumeration: RGBA
|
|
77
|
+
readonly markdownImage: RGBA
|
|
78
|
+
readonly markdownImageText: RGBA
|
|
79
|
+
readonly markdownCodeBlock: RGBA
|
|
80
|
+
readonly syntaxComment: RGBA
|
|
81
|
+
readonly syntaxKeyword: RGBA
|
|
82
|
+
readonly syntaxFunction: RGBA
|
|
83
|
+
readonly syntaxVariable: RGBA
|
|
84
|
+
readonly syntaxString: RGBA
|
|
85
|
+
readonly syntaxNumber: RGBA
|
|
86
|
+
readonly syntaxType: RGBA
|
|
87
|
+
readonly syntaxOperator: RGBA
|
|
88
|
+
readonly syntaxPunctuation: RGBA
|
|
89
|
+
readonly thinkingOpacity: number
|
|
90
|
+
_hasSelectedListItemText: boolean
|
|
91
|
+
}
|
|
92
|
+
type ThemeColor = Exclude<keyof Theme, "thinkingOpacity" | "_hasSelectedListItemText">
|
|
93
|
+
export type SyntaxStyleOverrides = Record<string, { italic?: boolean }>
|
|
94
|
+
|
|
95
|
+
export function selectedForeground(theme: Theme, bg?: RGBA): RGBA {
|
|
96
|
+
// If theme explicitly defines selectedListItemText, use it
|
|
97
|
+
if (theme._hasSelectedListItemText) {
|
|
98
|
+
return theme.selectedListItemText
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// For transparent backgrounds, calculate contrast based on the actual bg (or fallback to primary)
|
|
102
|
+
if (theme.background.a === 0) {
|
|
103
|
+
const targetColor = bg ?? theme.primary
|
|
104
|
+
const { r, g, b } = targetColor
|
|
105
|
+
const luminance = 0.299 * r + 0.587 * g + 0.114 * b
|
|
106
|
+
return luminance > 0.5 ? RGBA.fromInts(0, 0, 0) : RGBA.fromInts(255, 255, 255)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Fall back to background color
|
|
110
|
+
return theme.background
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
type HexColor = `#${string}`
|
|
114
|
+
type RefName = string
|
|
115
|
+
type Variant = {
|
|
116
|
+
dark: HexColor | RefName
|
|
117
|
+
light: HexColor | RefName
|
|
118
|
+
}
|
|
119
|
+
type ColorValue = HexColor | RefName | Variant | RGBA
|
|
120
|
+
export type ThemeJson = {
|
|
121
|
+
$schema?: string
|
|
122
|
+
defs?: Record<string, HexColor | RefName>
|
|
123
|
+
theme: Omit<Record<ThemeColor, ColorValue>, "selectedListItemText" | "backgroundMenu"> & {
|
|
124
|
+
selectedListItemText?: ColorValue
|
|
125
|
+
backgroundMenu?: ColorValue
|
|
126
|
+
thinkingOpacity?: number
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const DEFAULT_THEMES: Record<string, ThemeJson> = {
|
|
131
|
+
aura,
|
|
132
|
+
ayu,
|
|
133
|
+
catppuccin,
|
|
134
|
+
["catppuccin-frappe"]: catppuccinFrappe,
|
|
135
|
+
["catppuccin-macchiato"]: catppuccinMacchiato,
|
|
136
|
+
cobalt2,
|
|
137
|
+
cursor,
|
|
138
|
+
dracula,
|
|
139
|
+
everforest,
|
|
140
|
+
flexoki,
|
|
141
|
+
github,
|
|
142
|
+
gruvbox,
|
|
143
|
+
kanagawa,
|
|
144
|
+
material,
|
|
145
|
+
matrix,
|
|
146
|
+
mercury,
|
|
147
|
+
monokai,
|
|
148
|
+
nightowl,
|
|
149
|
+
nord,
|
|
150
|
+
["one-dark"]: onedark,
|
|
151
|
+
["osaka-jade"]: osakaJade,
|
|
152
|
+
opencode,
|
|
153
|
+
orng,
|
|
154
|
+
["lucent-orng"]: lucentOrng,
|
|
155
|
+
palenight,
|
|
156
|
+
rosepine,
|
|
157
|
+
solarized,
|
|
158
|
+
synthwave84,
|
|
159
|
+
tokyonight,
|
|
160
|
+
vesper,
|
|
161
|
+
vercel,
|
|
162
|
+
zenburn,
|
|
163
|
+
carbonfox,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const pluginThemes: Record<string, ThemeJson> = {}
|
|
167
|
+
let customThemes: Record<string, ThemeJson> = {}
|
|
168
|
+
let systemTheme: ThemeJson | undefined
|
|
169
|
+
const listeners = new Set<(themes: Record<string, ThemeJson>) => void>()
|
|
170
|
+
|
|
171
|
+
function listThemes() {
|
|
172
|
+
// Priority: defaults < plugin installs < custom files < generated system.
|
|
173
|
+
const themes = {
|
|
174
|
+
...DEFAULT_THEMES,
|
|
175
|
+
...pluginThemes,
|
|
176
|
+
...customThemes,
|
|
177
|
+
}
|
|
178
|
+
if (!systemTheme) return themes
|
|
179
|
+
return {
|
|
180
|
+
...themes,
|
|
181
|
+
system: systemTheme,
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function syncThemes() {
|
|
186
|
+
const themes = listThemes()
|
|
187
|
+
for (const listener of listeners) listener(themes)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function allThemes() {
|
|
191
|
+
return listThemes()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function isTheme(theme: unknown): theme is ThemeJson {
|
|
195
|
+
if (typeof theme !== "object" || theme === null || Array.isArray(theme)) return false
|
|
196
|
+
const value = Reflect.get(theme, "theme")
|
|
197
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function subscribeThemes(listener: (themes: Record<string, ThemeJson>) => void) {
|
|
201
|
+
listeners.add(listener)
|
|
202
|
+
return () => listeners.delete(listener)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function setCustomThemes(themes: Record<string, ThemeJson>) {
|
|
206
|
+
customThemes = themes
|
|
207
|
+
syncThemes()
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function setSystemTheme(theme: ThemeJson | undefined) {
|
|
211
|
+
systemTheme = theme
|
|
212
|
+
syncThemes()
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function hasTheme(name: string) {
|
|
216
|
+
if (!name) return false
|
|
217
|
+
return allThemes()[name] !== undefined
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function addTheme(name: string, theme: unknown) {
|
|
221
|
+
if (!name) return false
|
|
222
|
+
if (!isTheme(theme)) return false
|
|
223
|
+
if (hasTheme(name)) return false
|
|
224
|
+
pluginThemes[name] = theme
|
|
225
|
+
syncThemes()
|
|
226
|
+
return true
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function upsertTheme(name: string, theme: unknown) {
|
|
230
|
+
if (!name) return false
|
|
231
|
+
if (!isTheme(theme)) return false
|
|
232
|
+
if (customThemes[name] !== undefined) {
|
|
233
|
+
customThemes[name] = theme
|
|
234
|
+
} else {
|
|
235
|
+
pluginThemes[name] = theme
|
|
236
|
+
}
|
|
237
|
+
syncThemes()
|
|
238
|
+
return true
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
|
|
242
|
+
const defs = theme.defs ?? {}
|
|
243
|
+
function resolveColor(c: ColorValue, chain: string[] = []): RGBA {
|
|
244
|
+
if (c instanceof RGBA) return c
|
|
245
|
+
if (typeof c === "string") {
|
|
246
|
+
if (c === "transparent" || c === "none") return RGBA.fromInts(0, 0, 0, 0)
|
|
247
|
+
|
|
248
|
+
if (c.startsWith("#")) return RGBA.fromHex(c)
|
|
249
|
+
|
|
250
|
+
if (chain.includes(c)) {
|
|
251
|
+
throw new Error(`Circular color reference: ${[...chain, c].join(" -> ")}`)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const next = defs[c] ?? theme.theme[c as ThemeColor]
|
|
255
|
+
if (next === undefined) {
|
|
256
|
+
throw new Error(`Color reference "${c}" not found in defs or theme`)
|
|
257
|
+
}
|
|
258
|
+
return resolveColor(next, [...chain, c])
|
|
259
|
+
}
|
|
260
|
+
if (typeof c === "number") {
|
|
261
|
+
return ansiToRgba(c)
|
|
262
|
+
}
|
|
263
|
+
return resolveColor(c[mode], chain)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const resolved = Object.fromEntries(
|
|
267
|
+
Object.entries(theme.theme)
|
|
268
|
+
.filter(([key]) => key !== "selectedListItemText" && key !== "backgroundMenu" && key !== "thinkingOpacity")
|
|
269
|
+
.map(([key, value]) => {
|
|
270
|
+
return [key, resolveColor(value as ColorValue)]
|
|
271
|
+
}),
|
|
272
|
+
) as Partial<Record<ThemeColor, RGBA>>
|
|
273
|
+
|
|
274
|
+
// Handle selectedListItemText separately since it's optional
|
|
275
|
+
const hasSelectedListItemText = theme.theme.selectedListItemText !== undefined
|
|
276
|
+
if (hasSelectedListItemText) {
|
|
277
|
+
resolved.selectedListItemText = resolveColor(theme.theme.selectedListItemText!)
|
|
278
|
+
} else {
|
|
279
|
+
// Backward compatibility: if selectedListItemText is not defined, use background color
|
|
280
|
+
// This preserves the current behavior for all existing themes
|
|
281
|
+
resolved.selectedListItemText = resolved.background
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Handle backgroundMenu - optional with fallback to backgroundElement
|
|
285
|
+
if (theme.theme.backgroundMenu !== undefined) {
|
|
286
|
+
resolved.backgroundMenu = resolveColor(theme.theme.backgroundMenu)
|
|
287
|
+
} else {
|
|
288
|
+
resolved.backgroundMenu = resolved.backgroundElement
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Handle thinkingOpacity - optional with default of 0.6
|
|
292
|
+
const thinkingOpacity = theme.theme.thinkingOpacity ?? 0.6
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
...resolved,
|
|
296
|
+
_hasSelectedListItemText: hasSelectedListItemText,
|
|
297
|
+
thinkingOpacity,
|
|
298
|
+
} as Theme
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function ansiToRgba(code: number): RGBA {
|
|
302
|
+
// Standard ANSI colors (0-15)
|
|
303
|
+
if (code < 16) {
|
|
304
|
+
const ansiColors = [
|
|
305
|
+
"#000000", // Black
|
|
306
|
+
"#800000", // Red
|
|
307
|
+
"#008000", // Green
|
|
308
|
+
"#808000", // Yellow
|
|
309
|
+
"#000080", // Blue
|
|
310
|
+
"#800080", // Magenta
|
|
311
|
+
"#008080", // Cyan
|
|
312
|
+
"#c0c0c0", // White
|
|
313
|
+
"#808080", // Bright Black
|
|
314
|
+
"#ff0000", // Bright Red
|
|
315
|
+
"#00ff00", // Bright Green
|
|
316
|
+
"#ffff00", // Bright Yellow
|
|
317
|
+
"#0000ff", // Bright Blue
|
|
318
|
+
"#ff00ff", // Bright Magenta
|
|
319
|
+
"#00ffff", // Bright Cyan
|
|
320
|
+
"#ffffff", // Bright White
|
|
321
|
+
]
|
|
322
|
+
return RGBA.fromHex(ansiColors[code] ?? "#000000")
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// 6x6x6 Color Cube (16-231)
|
|
326
|
+
if (code < 232) {
|
|
327
|
+
const index = code - 16
|
|
328
|
+
const b = index % 6
|
|
329
|
+
const g = Math.floor(index / 6) % 6
|
|
330
|
+
const r = Math.floor(index / 36)
|
|
331
|
+
|
|
332
|
+
const val = (x: number) => (x === 0 ? 0 : x * 40 + 55)
|
|
333
|
+
return RGBA.fromInts(val(r), val(g), val(b))
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Grayscale Ramp (232-255)
|
|
337
|
+
if (code < 256) {
|
|
338
|
+
const gray = (code - 232) * 10 + 8
|
|
339
|
+
return RGBA.fromInts(gray, gray, gray)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Fallback for invalid codes
|
|
343
|
+
return RGBA.fromInts(0, 0, 0)
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export function tint(base: RGBA, overlay: RGBA, alpha: number): RGBA {
|
|
347
|
+
const r = base.r + (overlay.r - base.r) * alpha
|
|
348
|
+
const g = base.g + (overlay.g - base.g) * alpha
|
|
349
|
+
const b = base.b + (overlay.b - base.b) * alpha
|
|
350
|
+
return RGBA.fromInts(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255))
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export function terminalMode(colors: TerminalColors): "dark" | "light" | undefined {
|
|
354
|
+
const bg = colors.defaultBackground
|
|
355
|
+
if (!bg) return
|
|
356
|
+
const { r, g, b } = RGBA.fromHex(bg)
|
|
357
|
+
return 0.299 * r + 0.587 * g + 0.114 * b > 0.5 ? "light" : "dark"
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export function generateSystem(colors: TerminalColors, mode: "dark" | "light"): ThemeJson {
|
|
361
|
+
const bg = RGBA.fromHex(colors.defaultBackground ?? colors.palette[0]!)
|
|
362
|
+
const fg = RGBA.fromHex(colors.defaultForeground ?? colors.palette[7]!)
|
|
363
|
+
const transparent = RGBA.fromValues(bg.r, bg.g, bg.b, 0)
|
|
364
|
+
const isDark = mode == "dark"
|
|
365
|
+
|
|
366
|
+
const col = (i: number) => {
|
|
367
|
+
const value = colors.palette[i]
|
|
368
|
+
if (value) return RGBA.fromHex(value)
|
|
369
|
+
return ansiToRgba(i)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Generate gray scale based on terminal background
|
|
373
|
+
const grays = generateGrayScale(bg, isDark)
|
|
374
|
+
const textMuted = generateMutedTextColor(bg, isDark)
|
|
375
|
+
|
|
376
|
+
// ANSI color references
|
|
377
|
+
const ansiColors = {
|
|
378
|
+
black: col(0),
|
|
379
|
+
red: col(1),
|
|
380
|
+
green: col(2),
|
|
381
|
+
yellow: col(3),
|
|
382
|
+
blue: col(4),
|
|
383
|
+
magenta: col(5),
|
|
384
|
+
cyan: col(6),
|
|
385
|
+
white: col(7),
|
|
386
|
+
redBright: col(9),
|
|
387
|
+
greenBright: col(10),
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const diffAlpha = isDark ? 0.22 : 0.14
|
|
391
|
+
const diffAddedBg = tint(bg, ansiColors.green, diffAlpha)
|
|
392
|
+
const diffRemovedBg = tint(bg, ansiColors.red, diffAlpha)
|
|
393
|
+
const diffContextBg = grays[2]
|
|
394
|
+
const diffAddedLineNumberBg = tint(diffContextBg, ansiColors.green, diffAlpha)
|
|
395
|
+
const diffRemovedLineNumberBg = tint(diffContextBg, ansiColors.red, diffAlpha)
|
|
396
|
+
const diffLineNumber = textMuted
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
theme: {
|
|
400
|
+
// Primary colors using ANSI
|
|
401
|
+
primary: ansiColors.cyan,
|
|
402
|
+
secondary: ansiColors.magenta,
|
|
403
|
+
accent: ansiColors.cyan,
|
|
404
|
+
|
|
405
|
+
// Status colors using ANSI
|
|
406
|
+
error: ansiColors.red,
|
|
407
|
+
warning: ansiColors.yellow,
|
|
408
|
+
success: ansiColors.green,
|
|
409
|
+
info: ansiColors.cyan,
|
|
410
|
+
|
|
411
|
+
// Text colors
|
|
412
|
+
text: fg,
|
|
413
|
+
textMuted,
|
|
414
|
+
selectedListItemText: bg,
|
|
415
|
+
|
|
416
|
+
// Background colors - use transparent to respect terminal transparency
|
|
417
|
+
background: transparent,
|
|
418
|
+
backgroundPanel: grays[2],
|
|
419
|
+
backgroundElement: grays[3],
|
|
420
|
+
backgroundMenu: grays[3],
|
|
421
|
+
|
|
422
|
+
// Border colors
|
|
423
|
+
borderSubtle: grays[6],
|
|
424
|
+
border: grays[7],
|
|
425
|
+
borderActive: grays[8],
|
|
426
|
+
|
|
427
|
+
// Diff colors
|
|
428
|
+
diffAdded: ansiColors.green,
|
|
429
|
+
diffRemoved: ansiColors.red,
|
|
430
|
+
diffContext: grays[7],
|
|
431
|
+
diffHunkHeader: grays[7],
|
|
432
|
+
diffHighlightAdded: ansiColors.greenBright,
|
|
433
|
+
diffHighlightRemoved: ansiColors.redBright,
|
|
434
|
+
diffAddedBg,
|
|
435
|
+
diffRemovedBg,
|
|
436
|
+
diffContextBg,
|
|
437
|
+
diffLineNumber,
|
|
438
|
+
diffAddedLineNumberBg,
|
|
439
|
+
diffRemovedLineNumberBg,
|
|
440
|
+
|
|
441
|
+
// Markdown colors
|
|
442
|
+
markdownText: fg,
|
|
443
|
+
markdownHeading: fg,
|
|
444
|
+
markdownLink: ansiColors.blue,
|
|
445
|
+
markdownLinkText: ansiColors.cyan,
|
|
446
|
+
markdownCode: ansiColors.green,
|
|
447
|
+
markdownBlockQuote: ansiColors.yellow,
|
|
448
|
+
markdownEmph: ansiColors.yellow,
|
|
449
|
+
markdownStrong: fg,
|
|
450
|
+
markdownHorizontalRule: grays[7],
|
|
451
|
+
markdownListItem: ansiColors.blue,
|
|
452
|
+
markdownListEnumeration: ansiColors.cyan,
|
|
453
|
+
markdownImage: ansiColors.blue,
|
|
454
|
+
markdownImageText: ansiColors.cyan,
|
|
455
|
+
markdownCodeBlock: fg,
|
|
456
|
+
|
|
457
|
+
// Syntax colors
|
|
458
|
+
syntaxComment: textMuted,
|
|
459
|
+
syntaxKeyword: ansiColors.magenta,
|
|
460
|
+
syntaxFunction: ansiColors.blue,
|
|
461
|
+
syntaxVariable: fg,
|
|
462
|
+
syntaxString: ansiColors.green,
|
|
463
|
+
syntaxNumber: ansiColors.yellow,
|
|
464
|
+
syntaxType: ansiColors.cyan,
|
|
465
|
+
syntaxOperator: ansiColors.cyan,
|
|
466
|
+
syntaxPunctuation: fg,
|
|
467
|
+
},
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function generateGrayScale(bg: RGBA, isDark: boolean): Record<number, RGBA> {
|
|
472
|
+
const grays: Record<number, RGBA> = {}
|
|
473
|
+
|
|
474
|
+
// RGBA stores floats in range 0-1, convert to 0-255
|
|
475
|
+
const bgR = bg.r * 255
|
|
476
|
+
const bgG = bg.g * 255
|
|
477
|
+
const bgB = bg.b * 255
|
|
478
|
+
|
|
479
|
+
const luminance = 0.299 * bgR + 0.587 * bgG + 0.114 * bgB
|
|
480
|
+
|
|
481
|
+
for (let i = 1; i <= 12; i++) {
|
|
482
|
+
const factor = i / 12.0
|
|
483
|
+
|
|
484
|
+
let grayValue: number
|
|
485
|
+
let newR: number
|
|
486
|
+
let newG: number
|
|
487
|
+
let newB: number
|
|
488
|
+
|
|
489
|
+
if (isDark) {
|
|
490
|
+
if (luminance < 10) {
|
|
491
|
+
grayValue = Math.floor(factor * 0.4 * 255)
|
|
492
|
+
newR = grayValue
|
|
493
|
+
newG = grayValue
|
|
494
|
+
newB = grayValue
|
|
495
|
+
} else {
|
|
496
|
+
const newLum = luminance + (255 - luminance) * factor * 0.4
|
|
497
|
+
|
|
498
|
+
const ratio = newLum / luminance
|
|
499
|
+
newR = Math.min(bgR * ratio, 255)
|
|
500
|
+
newG = Math.min(bgG * ratio, 255)
|
|
501
|
+
newB = Math.min(bgB * ratio, 255)
|
|
502
|
+
}
|
|
503
|
+
} else {
|
|
504
|
+
if (luminance > 245) {
|
|
505
|
+
grayValue = Math.floor(255 - factor * 0.4 * 255)
|
|
506
|
+
newR = grayValue
|
|
507
|
+
newG = grayValue
|
|
508
|
+
newB = grayValue
|
|
509
|
+
} else {
|
|
510
|
+
const newLum = luminance * (1 - factor * 0.4)
|
|
511
|
+
|
|
512
|
+
const ratio = newLum / luminance
|
|
513
|
+
newR = Math.max(bgR * ratio, 0)
|
|
514
|
+
newG = Math.max(bgG * ratio, 0)
|
|
515
|
+
newB = Math.max(bgB * ratio, 0)
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
grays[i] = RGBA.fromInts(Math.floor(newR), Math.floor(newG), Math.floor(newB))
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return grays
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function generateMutedTextColor(bg: RGBA, isDark: boolean): RGBA {
|
|
526
|
+
// RGBA stores floats in range 0-1, convert to 0-255
|
|
527
|
+
const bgR = bg.r * 255
|
|
528
|
+
const bgG = bg.g * 255
|
|
529
|
+
const bgB = bg.b * 255
|
|
530
|
+
|
|
531
|
+
const bgLum = 0.299 * bgR + 0.587 * bgG + 0.114 * bgB
|
|
532
|
+
|
|
533
|
+
let grayValue: number
|
|
534
|
+
|
|
535
|
+
if (isDark) {
|
|
536
|
+
if (bgLum < 10) {
|
|
537
|
+
// Very dark/black background
|
|
538
|
+
grayValue = 180 // #b4b4b4
|
|
539
|
+
} else {
|
|
540
|
+
// Scale up for lighter dark backgrounds
|
|
541
|
+
grayValue = Math.min(Math.floor(160 + bgLum * 0.3), 200)
|
|
542
|
+
}
|
|
543
|
+
} else {
|
|
544
|
+
if (bgLum > 245) {
|
|
545
|
+
// Very light/white background
|
|
546
|
+
grayValue = 75 // #4b4b4b
|
|
547
|
+
} else {
|
|
548
|
+
// Scale down for darker light backgrounds
|
|
549
|
+
grayValue = Math.max(Math.floor(100 - (255 - bgLum) * 0.2), 60)
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
return RGBA.fromInts(grayValue, grayValue, grayValue)
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
export function generateSyntax(theme: Theme) {
|
|
557
|
+
return SyntaxStyle.fromTheme(getSyntaxRules(theme))
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export function generateSubtleSyntax(theme: Theme, overrides?: SyntaxStyleOverrides) {
|
|
561
|
+
const rules = getSyntaxRules(theme)
|
|
562
|
+
return SyntaxStyle.fromTheme(
|
|
563
|
+
rules.map((rule) => {
|
|
564
|
+
const override = rule.scope.reduce((acc, scope) => ({ ...acc, ...overrides?.[scope] }), {})
|
|
565
|
+
if (rule.style.foreground) {
|
|
566
|
+
const fg = rule.style.foreground
|
|
567
|
+
return {
|
|
568
|
+
...rule,
|
|
569
|
+
style: {
|
|
570
|
+
...rule.style,
|
|
571
|
+
...override,
|
|
572
|
+
foreground: RGBA.fromInts(
|
|
573
|
+
Math.round(fg.r * 255),
|
|
574
|
+
Math.round(fg.g * 255),
|
|
575
|
+
Math.round(fg.b * 255),
|
|
576
|
+
Math.round(theme.thinkingOpacity * 255),
|
|
577
|
+
),
|
|
578
|
+
},
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return rule
|
|
582
|
+
}),
|
|
583
|
+
)
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
function getSyntaxRules(theme: Theme) {
|
|
587
|
+
return [
|
|
588
|
+
{
|
|
589
|
+
scope: ["default"],
|
|
590
|
+
style: {
|
|
591
|
+
foreground: theme.text,
|
|
592
|
+
},
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
scope: ["prompt"],
|
|
596
|
+
style: {
|
|
597
|
+
foreground: theme.accent,
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
scope: ["extmark.file"],
|
|
602
|
+
style: {
|
|
603
|
+
foreground: theme.warning,
|
|
604
|
+
bold: true,
|
|
605
|
+
},
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
scope: ["extmark.agent"],
|
|
609
|
+
style: {
|
|
610
|
+
foreground: theme.secondary,
|
|
611
|
+
bold: true,
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
scope: ["extmark.paste"],
|
|
616
|
+
style: {
|
|
617
|
+
foreground: selectedForeground(theme, theme.warning),
|
|
618
|
+
background: theme.warning,
|
|
619
|
+
bold: true,
|
|
620
|
+
},
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
scope: ["comment"],
|
|
624
|
+
style: {
|
|
625
|
+
foreground: theme.syntaxComment,
|
|
626
|
+
italic: true,
|
|
627
|
+
},
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
scope: ["comment.documentation"],
|
|
631
|
+
style: {
|
|
632
|
+
foreground: theme.syntaxComment,
|
|
633
|
+
italic: true,
|
|
634
|
+
},
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
scope: ["string", "symbol"],
|
|
638
|
+
style: {
|
|
639
|
+
foreground: theme.syntaxString,
|
|
640
|
+
},
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
scope: ["number", "boolean"],
|
|
644
|
+
style: {
|
|
645
|
+
foreground: theme.syntaxNumber,
|
|
646
|
+
},
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
scope: ["character.special"],
|
|
650
|
+
style: {
|
|
651
|
+
foreground: theme.syntaxString,
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
scope: ["keyword.return", "keyword.conditional", "keyword.repeat", "keyword.coroutine"],
|
|
656
|
+
style: {
|
|
657
|
+
foreground: theme.syntaxKeyword,
|
|
658
|
+
italic: true,
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
scope: ["keyword.type"],
|
|
663
|
+
style: {
|
|
664
|
+
foreground: theme.syntaxType,
|
|
665
|
+
bold: true,
|
|
666
|
+
italic: true,
|
|
667
|
+
},
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
scope: ["keyword.function", "function.method"],
|
|
671
|
+
style: {
|
|
672
|
+
foreground: theme.syntaxFunction,
|
|
673
|
+
},
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
scope: ["keyword"],
|
|
677
|
+
style: {
|
|
678
|
+
foreground: theme.syntaxKeyword,
|
|
679
|
+
italic: true,
|
|
680
|
+
},
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
scope: ["keyword.import"],
|
|
684
|
+
style: {
|
|
685
|
+
foreground: theme.syntaxKeyword,
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
scope: ["operator", "keyword.operator", "punctuation.delimiter"],
|
|
690
|
+
style: {
|
|
691
|
+
foreground: theme.syntaxOperator,
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
scope: ["keyword.conditional.ternary"],
|
|
696
|
+
style: {
|
|
697
|
+
foreground: theme.syntaxOperator,
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
scope: ["variable", "variable.parameter", "function.method.call", "function.call"],
|
|
702
|
+
style: {
|
|
703
|
+
foreground: theme.syntaxVariable,
|
|
704
|
+
},
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
scope: ["variable.member", "function", "constructor"],
|
|
708
|
+
style: {
|
|
709
|
+
foreground: theme.syntaxFunction,
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
scope: ["type", "module"],
|
|
714
|
+
style: {
|
|
715
|
+
foreground: theme.syntaxType,
|
|
716
|
+
},
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
scope: ["constant"],
|
|
720
|
+
style: {
|
|
721
|
+
foreground: theme.syntaxNumber,
|
|
722
|
+
},
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
scope: ["property"],
|
|
726
|
+
style: {
|
|
727
|
+
foreground: theme.syntaxVariable,
|
|
728
|
+
},
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
scope: ["class"],
|
|
732
|
+
style: {
|
|
733
|
+
foreground: theme.syntaxType,
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
scope: ["parameter"],
|
|
738
|
+
style: {
|
|
739
|
+
foreground: theme.syntaxVariable,
|
|
740
|
+
},
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
scope: ["punctuation", "punctuation.bracket"],
|
|
744
|
+
style: {
|
|
745
|
+
foreground: theme.syntaxPunctuation,
|
|
746
|
+
},
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
scope: ["variable.builtin", "type.builtin", "function.builtin", "module.builtin", "constant.builtin"],
|
|
750
|
+
style: {
|
|
751
|
+
foreground: theme.error,
|
|
752
|
+
},
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
scope: ["variable.super"],
|
|
756
|
+
style: {
|
|
757
|
+
foreground: theme.error,
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
scope: ["string.escape", "string.regexp"],
|
|
762
|
+
style: {
|
|
763
|
+
foreground: theme.syntaxKeyword,
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
scope: ["keyword.directive"],
|
|
768
|
+
style: {
|
|
769
|
+
foreground: theme.syntaxKeyword,
|
|
770
|
+
italic: true,
|
|
771
|
+
},
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
scope: ["punctuation.special"],
|
|
775
|
+
style: {
|
|
776
|
+
foreground: theme.syntaxOperator,
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
scope: ["keyword.modifier"],
|
|
781
|
+
style: {
|
|
782
|
+
foreground: theme.syntaxKeyword,
|
|
783
|
+
italic: true,
|
|
784
|
+
},
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
scope: ["keyword.exception"],
|
|
788
|
+
style: {
|
|
789
|
+
foreground: theme.syntaxKeyword,
|
|
790
|
+
italic: true,
|
|
791
|
+
},
|
|
792
|
+
},
|
|
793
|
+
// Markdown specific styles
|
|
794
|
+
{
|
|
795
|
+
scope: ["markup.heading"],
|
|
796
|
+
style: {
|
|
797
|
+
foreground: theme.markdownHeading,
|
|
798
|
+
bold: true,
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
scope: ["markup.heading.1"],
|
|
803
|
+
style: {
|
|
804
|
+
foreground: theme.markdownHeading,
|
|
805
|
+
bold: true,
|
|
806
|
+
underline: true,
|
|
807
|
+
},
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
scope: ["markup.heading.2"],
|
|
811
|
+
style: {
|
|
812
|
+
foreground: theme.markdownHeading,
|
|
813
|
+
bold: true,
|
|
814
|
+
},
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
scope: ["markup.heading.3"],
|
|
818
|
+
style: {
|
|
819
|
+
foreground: theme.markdownHeading,
|
|
820
|
+
bold: true,
|
|
821
|
+
},
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
scope: ["markup.heading.4"],
|
|
825
|
+
style: {
|
|
826
|
+
foreground: theme.markdownHeading,
|
|
827
|
+
bold: true,
|
|
828
|
+
},
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
scope: ["markup.heading.5"],
|
|
832
|
+
style: {
|
|
833
|
+
foreground: theme.markdownHeading,
|
|
834
|
+
bold: true,
|
|
835
|
+
},
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
scope: ["markup.heading.6"],
|
|
839
|
+
style: {
|
|
840
|
+
foreground: theme.markdownHeading,
|
|
841
|
+
bold: true,
|
|
842
|
+
},
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
scope: ["markup.bold", "markup.strong"],
|
|
846
|
+
style: {
|
|
847
|
+
foreground: theme.markdownStrong,
|
|
848
|
+
bold: true,
|
|
849
|
+
},
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
scope: ["markup.italic"],
|
|
853
|
+
style: {
|
|
854
|
+
foreground: theme.markdownEmph,
|
|
855
|
+
italic: true,
|
|
856
|
+
},
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
scope: ["markup.list"],
|
|
860
|
+
style: {
|
|
861
|
+
foreground: theme.markdownListItem,
|
|
862
|
+
},
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
scope: ["markup.quote"],
|
|
866
|
+
style: {
|
|
867
|
+
foreground: theme.markdownBlockQuote,
|
|
868
|
+
italic: true,
|
|
869
|
+
},
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
scope: ["markup.raw", "markup.raw.block"],
|
|
873
|
+
style: {
|
|
874
|
+
foreground: theme.markdownCode,
|
|
875
|
+
},
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
scope: ["markup.raw.inline"],
|
|
879
|
+
style: {
|
|
880
|
+
foreground: theme.markdownCode,
|
|
881
|
+
background: theme.background,
|
|
882
|
+
},
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
scope: ["markup.link"],
|
|
886
|
+
style: {
|
|
887
|
+
foreground: theme.markdownLink,
|
|
888
|
+
underline: true,
|
|
889
|
+
},
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
scope: ["markup.link.label"],
|
|
893
|
+
style: {
|
|
894
|
+
foreground: theme.markdownLinkText,
|
|
895
|
+
underline: true,
|
|
896
|
+
},
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
scope: ["markup.link.url"],
|
|
900
|
+
style: {
|
|
901
|
+
foreground: theme.markdownLink,
|
|
902
|
+
underline: true,
|
|
903
|
+
},
|
|
904
|
+
},
|
|
905
|
+
{
|
|
906
|
+
scope: ["label"],
|
|
907
|
+
style: {
|
|
908
|
+
foreground: theme.markdownLinkText,
|
|
909
|
+
},
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
scope: ["spell", "nospell"],
|
|
913
|
+
style: {
|
|
914
|
+
foreground: theme.text,
|
|
915
|
+
},
|
|
916
|
+
},
|
|
917
|
+
{
|
|
918
|
+
scope: ["conceal"],
|
|
919
|
+
style: {
|
|
920
|
+
foreground: theme.textMuted,
|
|
921
|
+
},
|
|
922
|
+
},
|
|
923
|
+
// Additional common highlight groups
|
|
924
|
+
{
|
|
925
|
+
scope: ["string.special", "string.special.url"],
|
|
926
|
+
style: {
|
|
927
|
+
foreground: theme.markdownLink,
|
|
928
|
+
underline: true,
|
|
929
|
+
},
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
scope: ["character"],
|
|
933
|
+
style: {
|
|
934
|
+
foreground: theme.syntaxString,
|
|
935
|
+
},
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
scope: ["float"],
|
|
939
|
+
style: {
|
|
940
|
+
foreground: theme.syntaxNumber,
|
|
941
|
+
},
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
scope: ["comment.error"],
|
|
945
|
+
style: {
|
|
946
|
+
foreground: theme.error,
|
|
947
|
+
italic: true,
|
|
948
|
+
bold: true,
|
|
949
|
+
},
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
scope: ["comment.warning"],
|
|
953
|
+
style: {
|
|
954
|
+
foreground: theme.warning,
|
|
955
|
+
italic: true,
|
|
956
|
+
bold: true,
|
|
957
|
+
},
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
scope: ["comment.todo", "comment.note"],
|
|
961
|
+
style: {
|
|
962
|
+
foreground: theme.info,
|
|
963
|
+
italic: true,
|
|
964
|
+
bold: true,
|
|
965
|
+
},
|
|
966
|
+
},
|
|
967
|
+
{
|
|
968
|
+
scope: ["namespace"],
|
|
969
|
+
style: {
|
|
970
|
+
foreground: theme.syntaxType,
|
|
971
|
+
},
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
scope: ["field"],
|
|
975
|
+
style: {
|
|
976
|
+
foreground: theme.syntaxVariable,
|
|
977
|
+
},
|
|
978
|
+
},
|
|
979
|
+
{
|
|
980
|
+
scope: ["type.definition"],
|
|
981
|
+
style: {
|
|
982
|
+
foreground: theme.syntaxType,
|
|
983
|
+
bold: true,
|
|
984
|
+
},
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
scope: ["keyword.export"],
|
|
988
|
+
style: {
|
|
989
|
+
foreground: theme.syntaxKeyword,
|
|
990
|
+
},
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
scope: ["attribute", "annotation"],
|
|
994
|
+
style: {
|
|
995
|
+
foreground: theme.warning,
|
|
996
|
+
},
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
scope: ["tag"],
|
|
1000
|
+
style: {
|
|
1001
|
+
foreground: theme.error,
|
|
1002
|
+
},
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
scope: ["tag.attribute"],
|
|
1006
|
+
style: {
|
|
1007
|
+
foreground: theme.syntaxKeyword,
|
|
1008
|
+
},
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
scope: ["tag.delimiter"],
|
|
1012
|
+
style: {
|
|
1013
|
+
foreground: theme.syntaxOperator,
|
|
1014
|
+
},
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
scope: ["markup.strikethrough"],
|
|
1018
|
+
style: {
|
|
1019
|
+
foreground: theme.textMuted,
|
|
1020
|
+
},
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
scope: ["markup.underline"],
|
|
1024
|
+
style: {
|
|
1025
|
+
foreground: theme.text,
|
|
1026
|
+
underline: true,
|
|
1027
|
+
},
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
scope: ["markup.list.checked"],
|
|
1031
|
+
style: {
|
|
1032
|
+
foreground: theme.success,
|
|
1033
|
+
},
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
scope: ["markup.list.unchecked"],
|
|
1037
|
+
style: {
|
|
1038
|
+
foreground: theme.textMuted,
|
|
1039
|
+
},
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
scope: ["diff.plus"],
|
|
1043
|
+
style: {
|
|
1044
|
+
foreground: theme.diffAdded,
|
|
1045
|
+
background: theme.diffAddedBg,
|
|
1046
|
+
},
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
scope: ["diff.minus"],
|
|
1050
|
+
style: {
|
|
1051
|
+
foreground: theme.diffRemoved,
|
|
1052
|
+
background: theme.diffRemovedBg,
|
|
1053
|
+
},
|
|
1054
|
+
},
|
|
1055
|
+
{
|
|
1056
|
+
scope: ["diff.delta"],
|
|
1057
|
+
style: {
|
|
1058
|
+
foreground: theme.diffContext,
|
|
1059
|
+
background: theme.diffContextBg,
|
|
1060
|
+
},
|
|
1061
|
+
},
|
|
1062
|
+
{
|
|
1063
|
+
scope: ["error"],
|
|
1064
|
+
style: {
|
|
1065
|
+
foreground: theme.error,
|
|
1066
|
+
bold: true,
|
|
1067
|
+
},
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
scope: ["warning"],
|
|
1071
|
+
style: {
|
|
1072
|
+
foreground: theme.warning,
|
|
1073
|
+
bold: true,
|
|
1074
|
+
},
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
scope: ["info"],
|
|
1078
|
+
style: {
|
|
1079
|
+
foreground: theme.info,
|
|
1080
|
+
},
|
|
1081
|
+
},
|
|
1082
|
+
{
|
|
1083
|
+
scope: ["debug"],
|
|
1084
|
+
style: {
|
|
1085
|
+
foreground: theme.textMuted,
|
|
1086
|
+
},
|
|
1087
|
+
},
|
|
1088
|
+
]
|
|
1089
|
+
}
|