feat: add Flexoki themes for Shiki syntax highlighting

This commit is contained in:
Bohdan Triapitsyn
2025-12-15 00:20:26 +02:00
parent 5bf89ec7d1
commit 2b50f365bd
11 changed files with 1282 additions and 12 deletions
+2
View File
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
- Flexoki themes for Shiki syntax highlighting for consistency with the app color schema.
## [1.1.3] - 2025-12-14
+1 -1
View File
@@ -2847,7 +2847,7 @@ dependencies = [
[[package]]
name = "openchamber-desktop"
version = "1.1.2"
version = "1.1.3"
dependencies = [
"anyhow",
"axum",
@@ -5,7 +5,9 @@ import type { Part } from '@opencode-ai/sdk';
import { cn } from '@/lib/utils';
import { RiFileCopyLine, RiCheckLine, RiDownloadLine } from '@remixicon/react';
const SHIKI_THEMES = ['vitesse-light', 'vitesse-dark'] as const;
import { flexokiStreamdownThemes } from '@/lib/shiki/flexokiThemes';
const SHIKI_THEMES = flexokiStreamdownThemes;
// Table utility functions
const extractTableData = (tableEl: HTMLTableElement): { headers: string[]; rows: string[][] } => {
@@ -243,6 +245,50 @@ const CodeBlockWrapper: React.FC<CodeBlockWrapperProps> = ({ children, className
const [copied, setCopied] = React.useState(false);
const codeRef = React.useRef<HTMLDivElement>(null);
const normalizedStyle = React.useMemo<React.CSSProperties | undefined>(() => {
if (!style) return style;
const next: React.CSSProperties = { ...style };
const normalizeDeclarationString = (
raw: unknown
): { value?: string; vars: Record<string, string> } => {
if (typeof raw !== 'string') return { value: undefined, vars: {} };
const [valuePart, ...rest] = raw.split(';').map((p) => p.trim()).filter(Boolean);
const vars: Record<string, string> = {};
for (const decl of rest) {
const idx = decl.indexOf(':');
if (idx === -1) continue;
const prop = decl.slice(0, idx).trim();
const value = decl.slice(idx + 1).trim();
if (!prop.startsWith('--') || value.length === 0) continue;
vars[prop] = value;
}
return { value: valuePart, vars };
};
const bg = normalizeDeclarationString((style as React.CSSProperties).backgroundColor);
if (bg.value) {
next.backgroundColor = bg.value;
(next as Record<string, string>)['--shiki-light-bg'] = bg.value;
}
for (const [k, v] of Object.entries(bg.vars)) {
(next as Record<string, string>)[k] = v;
}
const fg = normalizeDeclarationString((style as React.CSSProperties).color);
if (fg.value) {
next.color = fg.value;
(next as Record<string, string>)['--shiki-light'] = fg.value;
}
for (const [k, v] of Object.entries(fg.vars)) {
(next as Record<string, string>)[k] = v;
}
return next;
}, [style]);
const getCodeContent = (): string => {
if (!codeRef.current) return '';
const codeEl = codeRef.current.querySelector('code');
@@ -267,11 +313,7 @@ const CodeBlockWrapper: React.FC<CodeBlockWrapperProps> = ({ children, className
<pre
{...props}
className={cn(className)}
style={{
...style,
background: 'transparent',
backgroundColor: 'transparent',
}}
style={normalizedStyle}
>
{children}
</pre>
@@ -4,6 +4,8 @@ import { parseDiffFromFile, type FileContents, type FileDiffMetadata } from '@pi
import { useOptionalThemeSystem } from '@/contexts/useThemeSystem';
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
import { ensureFlexokiThemesRegistered } from '@/lib/shiki/registerFlexokiThemes';
import { flexokiThemeNames } from '@/lib/shiki/flexokiThemes';
interface PierreDiffViewerProps {
original: string;
@@ -51,6 +53,8 @@ export const PierreDiffViewer: React.FC<PierreDiffViewerProps> = ({
const themeSystem = useOptionalThemeSystem();
const isDark = themeSystem?.currentTheme?.metadata?.variant === 'dark';
ensureFlexokiThemesRegistered();
// Cache the last computed diff to avoid recomputing on every render
const diffCacheRef = useRef<{
key: string;
@@ -90,8 +94,8 @@ export const PierreDiffViewer: React.FC<PierreDiffViewerProps> = ({
const options = useMemo(() => ({
theme: {
dark: 'vitesse-dark' as const,
light: 'vitesse-light' as const,
dark: flexokiThemeNames.dark,
light: flexokiThemeNames.light,
},
themeType: isDark ? ('dark' as const) : ('light' as const),
diffStyle: renderSideBySide ? ('split' as const) : ('unified' as const),
@@ -4,6 +4,8 @@ import type { SupportedLanguages } from '@pierre/diffs';
import { useOptionalThemeSystem } from './useThemeSystem';
import { workerFactory } from '@/lib/diff/workerFactory';
import { ensureFlexokiThemesRegistered } from '@/lib/shiki/registerFlexokiThemes';
import { flexokiThemeNames } from '@/lib/shiki/flexokiThemes';
// Only preload the most common languages - others load on demand
const PRELOAD_LANGS: SupportedLanguages[] = [
@@ -21,10 +23,12 @@ export const DiffWorkerProvider: React.FC<DiffWorkerProviderProps> = ({ children
const themeSystem = useOptionalThemeSystem();
const isDark = themeSystem?.currentTheme?.metadata?.variant === 'dark';
ensureFlexokiThemesRegistered();
const highlighterOptions = useMemo(() => ({
theme: {
dark: 'vitesse-dark' as const,
light: 'vitesse-light' as const,
dark: flexokiThemeNames.dark,
light: flexokiThemeNames.light,
},
themeType: isDark ? ('dark' as const) : ('light' as const),
langs: PRELOAD_LANGS,
+15
View File
@@ -1301,6 +1301,21 @@ html:not(.dark) .chat-scroll {
font-family: var(--font-mono);
}
/* Streamdown code blocks: ensure light/dark Shiki vars work even when Tailwind doesn't scan Streamdown's internal class names. */
.streamdown-content [data-streamdown="code-block-body"] {
background-color: var(--shiki-light-bg, transparent);
color: var(--shiki-light, inherit);
}
.dark .streamdown-content [data-streamdown="code-block-body"] {
background-color: var(--shiki-dark-bg, var(--shiki-light-bg, transparent));
color: var(--shiki-dark, var(--shiki-light, inherit));
}
.dark .streamdown-content [data-streamdown="code-block-body"] span[style*="--shiki-dark"] {
color: var(--shiki-dark) !important;
}
/* Fix list styling - override Tailwind reset */
.streamdown-content ul {
list-style-type: disc;
@@ -0,0 +1,94 @@
import flexokiDarkRawJson from './themes/flexoki-dark.json';
import flexokiLightRawJson from './themes/flexoki-light.json';
export const FLEXOKI_SHIKI_DARK_THEME_NAME = 'flexoki-dark';
export const FLEXOKI_SHIKI_LIGHT_THEME_NAME = 'flexoki-light';
type VSCodeTokenColorRule = {
name?: string;
scope?: string | string[];
settings: Record<string, string | undefined>;
};
type VSCodeTextMateTheme = {
name: string;
type: 'dark' | 'light';
colors?: Record<string, string>;
tokenColors?: VSCodeTokenColorRule[];
semanticHighlighting?: boolean;
semanticTokenColors?: Record<string, string>;
};
type ShikiThemeRegistrationResolvedLike = VSCodeTextMateTheme & {
settings: VSCodeTokenColorRule[];
fg: string;
bg: string;
};
const flexokiDarkRaw = flexokiDarkRawJson as VSCodeTextMateTheme;
const flexokiLightRaw = flexokiLightRawJson as VSCodeTextMateTheme;
function withStableStringId<T extends object>(value: T, id: string): T {
Object.defineProperty(value, 'toString', {
value: () => id,
enumerable: false,
});
Object.defineProperty(value, Symbol.toPrimitive, {
value: () => id,
enumerable: false,
});
return value;
}
function toResolvedTheme(
raw: VSCodeTextMateTheme,
name: string,
type: VSCodeTextMateTheme['type']
): ShikiThemeRegistrationResolvedLike {
const bg = raw.colors?.['editor.background'];
const fg = raw.colors?.['editor.foreground'];
if (!bg || !fg) {
throw new Error(
`Flexoki Shiki theme "${name}" is missing editor.background/editor.foreground`
);
}
const settings = raw.tokenColors ?? [];
return {
...raw,
name,
type,
fg,
bg,
settings,
};
}
export const flexokiDarkTheme = toResolvedTheme(
flexokiDarkRaw,
FLEXOKI_SHIKI_DARK_THEME_NAME,
'dark'
);
export const flexokiLightTheme = toResolvedTheme(
flexokiLightRaw,
FLEXOKI_SHIKI_LIGHT_THEME_NAME,
'light'
);
withStableStringId(flexokiDarkTheme, FLEXOKI_SHIKI_DARK_THEME_NAME);
withStableStringId(flexokiLightTheme, FLEXOKI_SHIKI_LIGHT_THEME_NAME);
export const flexokiThemeNames = {
dark: FLEXOKI_SHIKI_DARK_THEME_NAME,
light: FLEXOKI_SHIKI_LIGHT_THEME_NAME,
} as const;
export const flexokiStreamdownThemes = [
flexokiLightTheme,
flexokiDarkTheme,
] as const;
@@ -0,0 +1,15 @@
import { registerCustomTheme } from '@pierre/diffs';
import { flexokiDarkTheme, flexokiLightTheme, flexokiThemeNames } from './flexokiThemes';
let hasRegistered = false;
export function ensureFlexokiThemesRegistered(): void {
if (hasRegistered) return;
registerCustomTheme(flexokiThemeNames.dark, async () => flexokiDarkTheme);
registerCustomTheme(flexokiThemeNames.light, async () => flexokiLightTheme);
hasRegistered = true;
}
@@ -0,0 +1,547 @@
{
"name": "Flexoki",
"type": "dark",
"colors": {
"editor.background": "#100F0F",
"editor.foreground": "#CECDC3",
"editor.hoverHighlightBackground": "#343331",
"editor.lineHighlightBackground": "#1C1B1A",
"editor.selectionBackground": "#CECDC333",
"editor.selectionHighlightBackground": "#CECDC333",
"editor.findMatchBackground": "#AD8301",
"editor.findMatchHighlightBackground": "#AD8301cc",
"editor.findRangeHighlightBackground": "#1C1B1A",
"editor.inactiveSelectionBackground": "#282726",
"editor.lineHighlightBorder": "#282726",
"editor.rangeHighlightBackground": "#403E3C",
"notifications.background": "#282726",
"editorInlayHint.typeBackground": "#343331",
"editorInlayHint.typeForeground": "#CECDC3",
"editorWhitespace.foreground": "#403E3C",
"editorIndentGuide.background1": "#343331",
"editorHoverWidget.background": "#282726",
"editorLineNumber.activeForeground": "#CECDC3",
"editorLineNumber.foreground": "#403E3C",
"editorGutter.background": "#100F0F",
"editorGutter.modifiedBackground": "#3AA99F",
"editorGutter.addedBackground": "#879A39",
"editorGutter.deletedBackground": "#D14D41",
"editorBracketMatch.background": "#282726",
"editorBracketMatch.border": "#343331",
"editorError.foreground": "#D14D41",
"editorWarning.foreground": "#DA702C",
"editorInfo.foreground": "#4385BE",
"diffEditor.insertedTextBackground": "#66800B99",
"diffEditor.removedTextBackground": "#AF302999",
"editorGroupHeader.tabsBackground": "#100F0F",
"editorGroup.border": "#343331",
"tab.activeBackground": "#100F0F",
"tab.inactiveBackground": "#1C1B1A",
"tab.inactiveForeground": "#878580",
"tab.activeForeground": "#CECDC3",
"tab.hoverBackground": "#343331",
"tab.unfocusedHoverBackground": "#343331",
"tab.border": "#343331",
"tab.activeModifiedBorder": "#D0A215",
"tab.inactiveModifiedBorder": "#4385BE",
"tab.unfocusedActiveModifiedBorder": "#AD8301",
"tab.unfocusedInactiveModifiedBorder": "#205EA6",
"editorWidget.background": "#1C1B1A",
"editorWidget.border": "#343331",
"editorSuggestWidget.background": "#100F0F",
"editorSuggestWidget.border": "#343331",
"editorSuggestWidget.foreground": "#CECDC3",
"editorSuggestWidget.highlightForeground": "#878580",
"editorSuggestWidget.selectedBackground": "#343331",
"peekView.border": "#343331",
"peekViewEditor.background": "#100F0F",
"peekViewEditor.matchHighlightBackground": "#403E3C",
"peekViewResult.background": "#1C1B1A",
"peekViewResult.fileForeground": "#CECDC3",
"peekViewResult.lineForeground": "#878580",
"peekViewResult.matchHighlightBackground": "#403E3C",
"peekViewResult.selectionBackground": "#282726",
"peekViewResult.selectionForeground": "#575653",
"peekViewTitle.background": "#343331",
"peekViewTitleDescription.foreground": "#878580",
"peekViewTitleLabel.foreground": "#CECDC3",
"merge.currentHeaderBackground": "#879A39",
"merge.currentContentBackground": "#66800B",
"merge.incomingHeaderBackground": "#3AA99F",
"merge.incomingContentBackground": "#24837B",
"merge.border": "#343331",
"merge.commonContentBackground": "#403E3C",
"merge.commonHeaderBackground": "#343331",
"panel.background": "#100F0F",
"panel.border": "#343331",
"panelTitle.activeBorder": "#403E3C",
"panelTitle.activeForeground": "#CECDC3",
"panelTitle.inactiveForeground": "#878580",
"statusBar.background": "#100F0F",
"statusBar.foreground": "#CECDC3",
"statusBar.border": "#343331",
"statusBar.debuggingBackground": "#D14D41",
"statusBar.debuggingForeground": "#CECDC3",
"statusBar.noFolderBackground": "#403E3C",
"statusBar.noFolderForeground": "#575653",
"titleBar.activeBackground": "#100F0F",
"titleBar.activeForeground": "#CECDC3",
"titleBar.inactiveBackground": "#1C1B1A",
"titleBar.inactiveForeground": "#878580",
"titleBar.border": "#343331",
"menu.foreground": "#CECDC3",
"menu.background": "#100F0F",
"menu.selectionForeground": "#CECDC3",
"menu.selectionBackground": "#343331",
"menu.border": "#343331",
"editorInlayHint.foreground": "#878580",
"editorInlayHint.background": "#343331",
"terminal.foreground": "#CECDC3",
"terminal.background": "#100F0F",
"terminalCursor.foreground": "#CECDC3",
"terminalCursor.background": "#100F0F",
"terminal.ansiRed": "#D14D41",
"terminal.ansiGreen": "#879A39",
"terminal.ansiYellow": "#D0A215",
"terminal.ansiBlue": "#4385BE",
"terminal.ansiMagenta": "#3AA99F",
"terminal.ansiCyan": "#3AA99F",
"activityBar.background": "#100F0F",
"activityBar.foreground": "#CECDC3",
"activityBar.inactiveForeground": "#878580",
"activityBar.activeBorder": "#CECDC3",
"activityBar.border": "#343331",
"sideBar.background": "#100F0F",
"sideBar.foreground": "#CECDC3",
"sideBar.border": "#343331",
"sideBarTitle.foreground": "#CECDC3",
"sideBarSectionHeader.background": "#1C1B1A",
"sideBarSectionHeader.foreground": "#CECDC3",
"sideBarSectionHeader.border": "#343331",
"sideBar.activeBackground": "#403E3C",
"sideBar.activeForeground": "#CECDC3",
"sideBar.hoverBackground": "#343331",
"sideBar.hoverForeground": "#878580",
"sideBar.folderIcon.foreground": "#879A39",
"sideBar.fileIcon.foreground": "#4385BE",
"list.warningForeground": "#DA702C",
"list.errorForeground": "#D14D41",
"list.inactiveSelectionBackground": "#343331",
"list.activeSelectionBackground": "#403E3C",
"list.inactiveSelectionForeground": "#CECDC3",
"list.activeSelectionForeground": "#CECDC3",
"list.hoverForeground": "#CECDC3",
"list.hoverBackground": "#343331",
"input.background": "#1C1B1A",
"input.foreground": "#CECDC3",
"input.border": "#343331",
"input.placeholderForeground": "#878580",
"inputOption.activeBorder": "#343331",
"inputOption.activeBackground": "#282726",
"inputOption.activeForeground": "#CECDC3",
"inputValidation.infoBackground": "#3AA99F",
"inputValidation.infoBorder": "#24837B",
"inputValidation.warningBackground": "#DA702C",
"inputValidation.warningBorder": "#BC5215",
"inputValidation.errorBackground": "#D14D41",
"inputValidation.errorBorder": "#AF3029",
"dropdown.background": "#1C1B1A",
"dropdown.foreground": "#CECDC3",
"dropdown.border": "#343331",
"dropdown.listBackground": "#100F0F",
"badge.background": "#3AA99F",
"activityBarBadge.background": "#3AA99F",
"button.background": "#3AA99F",
"button.foreground": "#100F0F",
"badge.foreground": "#100F0F",
"activityBarBadge.foreground": "#100F0F"
},
"tokenColors": [
{
"name": "plain",
"scope": ["source", "support.type.property-name.css"],
"settings": {
"foreground": "#CECDC3"
}
},
{
"name": "classes",
"scope": ["entity.name.type.class"],
"settings": {
"foreground": "#DA702C"
}
},
{
"name": "interfaces",
"scope": ["entity.name.type.interface", "entity.name.type"],
"settings": {
"foreground": "#D0A215"
}
},
{
"name": "structs",
"scope": ["entity.name.type.struct"],
"settings": {
"foreground": "#DA702C"
}
},
{
"name": "enums",
"scope": ["entity.name.type.enum"],
"settings": {
"foreground": "#DA702C"
}
},
{
"name": "keys",
"scope": ["meta.object-literal.key", "support.type.property-name"],
"settings": {
"foreground": "#DA702C"
}
},
{
"name": "methods",
"scope": ["entity.name.function.method", "meta.function.method"],
"settings": {
"foreground": "#879A39"
}
},
{
"name": "functions",
"scope": [
"entity.name.function",
"support.function",
"meta.function-call.generic"
],
"settings": {
"foreground": "#DA702C",
"fontStyle": "bold"
}
},
{
"name": "variables",
"scope": ["variable", "meta.variable", "variable.other.object.property"],
"settings": {
"foreground": "#CECDC3"
}
},
{
"name": "variablesOther",
"scope": ["variable.other.object", "variable.other.readwrite.alias"],
"settings": {
"foreground": "#879A39"
}
},
{
"name": "globalVariables",
"scope": ["variable.other.global", "variable.language.this"],
"settings": {
"foreground": "#CE5D97"
}
},
{
"name": "localVariables",
"scope": ["variable.other.local"],
"settings": {
"foreground": "#282726"
}
},
{
"name": "parameters",
"scope": ["variable.parameter", "meta.parameter"],
"settings": {
"foreground": "#CECDC3"
}
},
{
"name": "properties",
"scope": ["variable.other.property", "meta.property"],
"settings": {
"foreground": "#4385BE"
}
},
{
"name": "strings",
"scope": [
"string",
"string.other.link",
"markup.inline.raw.string.markdown"
],
"settings": {
"foreground": "#3AA99F"
}
},
{
"name": "stringEscapeSequences",
"scope": ["constant.character.escape", "constant.other.placeholder"],
"settings": {
"foreground": "#CECDC3"
}
},
{
"name": "keywords",
"scope": ["keyword"],
"settings": {
"foreground": "#879A39"
}
},
{
"name": "keywordsControl",
"scope": [
"keyword.control.import",
"keyword.control.from",
"keyword.import"
],
"settings": {
"foreground": "#D14D41"
}
},
{
"name": "storageModifiers",
"scope": ["storage.modifier", "keyword.modifier", "storage.type"],
"settings": {
"foreground": "#4385BE"
}
},
{
"name": "comments",
"scope": ["comment", "punctuation.definition.comment"],
"settings": {
"foreground": "#878580"
}
},
{
"name": "docComments",
"scope": ["comment.documentation", "comment.line.documentation"],
"settings": {
"foreground": "#575653"
}
},
{
"name": "numbers",
"scope": ["constant.numeric"],
"settings": {
"foreground": "#8B7EC8"
}
},
{
"name": "booleans",
"scope": ["constant.language.boolean", "constant.language.json"],
"settings": {
"foreground": "#D0A215"
}
},
{
"name": "operators",
"scope": ["keyword.operator"],
"settings": {
"foreground": "#D14D41"
}
},
{
"name": "macros",
"scope": ["entity.name.function.preprocessor", "meta.preprocessor"],
"settings": {
"foreground": "#4385BE"
}
},
{
"name": "preprocessor",
"scope": ["meta.preprocessor"],
"settings": {
"foreground": "#CE5D97"
}
},
{
"name": "urls",
"scope": ["markup.underline.link"],
"settings": {
"foreground": "#4385BE"
}
},
{
"name": "tags",
"scope": ["entity.name.tag"],
"settings": {
"foreground": "#4385BE"
}
},
{
"name": "jsxTags",
"scope": ["support.class.component"],
"settings": {
"foreground": "#CE5D97"
}
},
{
"name": "attributes",
"scope": ["entity.other.attribute-name", "meta.attribute"],
"settings": {
"foreground": "#D0A215"
}
},
{
"name": "types",
"scope": ["support.type"],
"settings": {
"foreground": "#D0A215"
}
},
{
"name": "constants",
"scope": ["variable.other.constant", "variable.readonly"],
"settings": {
"foreground": "#CECDC3"
}
},
{
"name": "labels",
"scope": ["entity.name.label", "punctuation.definition.label"],
"settings": {
"foreground": "#CE5D97"
}
},
{
"name": "namespaces",
"scope": [
"entity.name.namespace",
"storage.modifier.namespace",
"markup.bold.markdown"
],
"settings": {
"foreground": "#D0A215"
}
},
{
"name": "modules",
"scope": ["entity.name.module", "storage.modifier.module"],
"settings": {
"foreground": "#D14D41"
}
},
{
"name": "typeParameters",
"scope": ["variable.type.parameter", "variable.parameter.type"],
"settings": {
"foreground": "#DA702C"
}
},
{
"name": "exceptions",
"scope": ["keyword.control.exception", "keyword.control.trycatch"],
"settings": {
"foreground": "#CE5D97"
}
},
{
"name": "decorators",
"scope": [
"meta.decorator",
"punctuation.decorator",
"entity.name.function.decorator"
],
"settings": {
"foreground": "#D0A215"
}
},
{
"name": "calls",
"scope": ["variable.function"],
"settings": {
"foreground": "#CECDC3"
}
},
{
"name": "punctuation",
"scope": [
"punctuation",
"punctuation.terminator",
"punctuation.definition.tag",
"punctuation.separator",
"punctuation.definition.string",
"punctuation.section.block"
],
"settings": {
"foreground": "#878580"
}
},
{
"name": "yellow",
"scope": [
"storage.type.numeric.go",
"storage.type.byte.go",
"storage.type.boolean.go",
"storage.type.string.go",
"storage.type.uintptr.go",
"storage.type.error.go",
"storage.type.rune.go",
"constant.language.go",
"support.class.dart",
"keyword.other.documentation",
"storage.modifier.import.java",
"punctuation.definition.list.begin.markdown",
"punctuation.definition.quote.begin.markdown",
"meta.separator.markdown",
"entity.name.section.markdown"
],
"settings": {
"foreground": "#D0A215"
}
},
{
"name": "green",
"scope": [],
"settings": {
"foreground": "#879A39"
}
},
{
"name": "cyan",
"scope": [
"markup.italic.markdown",
"support.type.python",
"variable.legacy.builtin.python",
"support.constant.property-value.css",
"storage.modifier.attribute.swift"
],
"settings": {
"foreground": "#3AA99F"
}
},
{
"name": "blue",
"scope": [],
"settings": {
"foreground": "#4385BE"
}
},
{
"name": "purple",
"scope": ["keyword.channel.go", "keyword.other.platform.os.swift"],
"settings": {
"foreground": "#8B7EC8"
}
},
{
"name": "magenta",
"scope": ["punctuation.definition.heading.markdown"],
"settings": {
"foreground": "#CE5D97"
}
},
{
"name": "red",
"scope": [],
"settings": {
"foreground": "#D14D41"
}
},
{
"name": "orange",
"scope": [],
"settings": {
"foreground": "#DA702C"
}
}
]
}
@@ -0,0 +1,547 @@
{
"name": "Flexoki",
"type": "light",
"colors": {
"editor.background": "#FFFCF0",
"editor.foreground": "#100F0F",
"editor.hoverHighlightBackground": "#DAD8CE",
"editor.lineHighlightBackground": "#F2F0E5",
"editor.selectionBackground": "#100F0F44",
"editor.selectionHighlightBackground": "#100F0F44",
"editor.findMatchBackground": "#D0A215",
"editor.findMatchHighlightBackground": "#D0A215cc",
"editor.findRangeHighlightBackground": "#F2F0E5",
"editor.inactiveSelectionBackground": "#E6E4D9",
"editor.lineHighlightBorder": "#E6E4D9",
"editor.rangeHighlightBackground": "#CECDC3",
"notifications.background": "#E6E4D9",
"editorInlayHint.typeBackground": "#DAD8CE",
"editorInlayHint.typeForeground": "#100F0F",
"editorWhitespace.foreground": "#CECDC3",
"editorIndentGuide.background1": "#DAD8CE",
"editorHoverWidget.background": "#E6E4D9",
"editorLineNumber.activeForeground": "#100F0F",
"editorLineNumber.foreground": "#CECDC3",
"editorGutter.background": "#FFFCF0",
"editorGutter.modifiedBackground": "#24837B",
"editorGutter.addedBackground": "#66800B",
"editorGutter.deletedBackground": "#AF3029",
"editorBracketMatch.background": "#E6E4D9",
"editorBracketMatch.border": "#DAD8CE",
"editorError.foreground": "#AF3029",
"editorWarning.foreground": "#BC5215",
"editorInfo.foreground": "#205EA6",
"diffEditor.insertedTextBackground": "#879A3999",
"diffEditor.removedTextBackground": "#D14D4199",
"editorGroupHeader.tabsBackground": "#FFFCF0",
"editorGroup.border": "#DAD8CE",
"tab.activeBackground": "#FFFCF0",
"tab.inactiveBackground": "#F2F0E5",
"tab.inactiveForeground": "#6F6E69",
"tab.activeForeground": "#100F0F",
"tab.hoverBackground": "#DAD8CE",
"tab.unfocusedHoverBackground": "#DAD8CE",
"tab.border": "#DAD8CE",
"tab.activeModifiedBorder": "#AD8301",
"tab.inactiveModifiedBorder": "#205EA6",
"tab.unfocusedActiveModifiedBorder": "#D0A215",
"tab.unfocusedInactiveModifiedBorder": "#4385BE",
"editorWidget.background": "#F2F0E5",
"editorWidget.border": "#DAD8CE",
"editorSuggestWidget.background": "#FFFCF0",
"editorSuggestWidget.border": "#DAD8CE",
"editorSuggestWidget.foreground": "#100F0F",
"editorSuggestWidget.highlightForeground": "#6F6E69",
"editorSuggestWidget.selectedBackground": "#DAD8CE",
"peekView.border": "#DAD8CE",
"peekViewEditor.background": "#FFFCF0",
"peekViewEditor.matchHighlightBackground": "#CECDC3",
"peekViewResult.background": "#F2F0E5",
"peekViewResult.fileForeground": "#100F0F",
"peekViewResult.lineForeground": "#6F6E69",
"peekViewResult.matchHighlightBackground": "#CECDC3",
"peekViewResult.selectionBackground": "#E6E4D9",
"peekViewResult.selectionForeground": "#B7B5AC",
"peekViewTitle.background": "#DAD8CE",
"peekViewTitleDescription.foreground": "#6F6E69",
"peekViewTitleLabel.foreground": "#100F0F",
"merge.currentHeaderBackground": "#66800B",
"merge.currentContentBackground": "#879A39",
"merge.incomingHeaderBackground": "#24837B",
"merge.incomingContentBackground": "#3AA99F",
"merge.border": "#DAD8CE",
"merge.commonContentBackground": "#CECDC3",
"merge.commonHeaderBackground": "#DAD8CE",
"panel.background": "#FFFCF0",
"panel.border": "#DAD8CE",
"panelTitle.activeBorder": "#CECDC3",
"panelTitle.activeForeground": "#100F0F",
"panelTitle.inactiveForeground": "#6F6E69",
"statusBar.background": "#FFFCF0",
"statusBar.foreground": "#100F0F",
"statusBar.border": "#DAD8CE",
"statusBar.debuggingBackground": "#AF3029",
"statusBar.debuggingForeground": "#100F0F",
"statusBar.noFolderBackground": "#CECDC3",
"statusBar.noFolderForeground": "#B7B5AC",
"titleBar.activeBackground": "#FFFCF0",
"titleBar.activeForeground": "#100F0F",
"titleBar.inactiveBackground": "#F2F0E5",
"titleBar.inactiveForeground": "#6F6E69",
"titleBar.border": "#DAD8CE",
"menu.foreground": "#100F0F",
"menu.background": "#FFFCF0",
"menu.selectionForeground": "#100F0F",
"menu.selectionBackground": "#DAD8CE",
"menu.border": "#DAD8CE",
"editorInlayHint.foreground": "#6F6E69",
"editorInlayHint.background": "#DAD8CE",
"terminal.foreground": "#100F0F",
"terminal.background": "#FFFCF0",
"terminalCursor.foreground": "#100F0F",
"terminalCursor.background": "#FFFCF0",
"terminal.ansiRed": "#AF3029",
"terminal.ansiGreen": "#66800B",
"terminal.ansiYellow": "#AD8301",
"terminal.ansiBlue": "#205EA6",
"terminal.ansiMagenta": "#24837B",
"terminal.ansiCyan": "#24837B",
"activityBar.background": "#FFFCF0",
"activityBar.foreground": "#100F0F",
"activityBar.inactiveForeground": "#6F6E69",
"activityBar.activeBorder": "#100F0F",
"activityBar.border": "#DAD8CE",
"sideBar.background": "#FFFCF0",
"sideBar.foreground": "#100F0F",
"sideBar.border": "#DAD8CE",
"sideBarTitle.foreground": "#100F0F",
"sideBarSectionHeader.background": "#F2F0E5",
"sideBarSectionHeader.foreground": "#100F0F",
"sideBarSectionHeader.border": "#DAD8CE",
"sideBar.activeBackground": "#CECDC3",
"sideBar.activeForeground": "#100F0F",
"sideBar.hoverBackground": "#DAD8CE",
"sideBar.hoverForeground": "#6F6E69",
"sideBar.folderIcon.foreground": "#66800B",
"sideBar.fileIcon.foreground": "#205EA6",
"list.warningForeground": "#BC5215",
"list.errorForeground": "#AF3029",
"list.inactiveSelectionBackground": "#DAD8CE",
"list.activeSelectionBackground": "#CECDC3",
"list.inactiveSelectionForeground": "#100F0F",
"list.activeSelectionForeground": "#100F0F",
"list.hoverForeground": "#100F0F",
"list.hoverBackground": "#DAD8CE",
"input.background": "#F2F0E5",
"input.foreground": "#100F0F",
"input.border": "#DAD8CE",
"input.placeholderForeground": "#6F6E69",
"inputOption.activeBorder": "#DAD8CE",
"inputOption.activeBackground": "#E6E4D9",
"inputOption.activeForeground": "#100F0F",
"inputValidation.infoBackground": "#24837B",
"inputValidation.infoBorder": "#3AA99F",
"inputValidation.warningBackground": "#BC5215",
"inputValidation.warningBorder": "#DA702C",
"inputValidation.errorBackground": "#AF3029",
"inputValidation.errorBorder": "#D14D41",
"dropdown.background": "#F2F0E5",
"dropdown.foreground": "#100F0F",
"dropdown.border": "#DAD8CE",
"dropdown.listBackground": "#FFFCF0",
"badge.background": "#24837B",
"activityBarBadge.background": "#24837B",
"button.background": "#24837B",
"button.foreground": "#FFFCF0",
"badge.foreground": "#FFFCF0",
"activityBarBadge.foreground": "#FFFCF0"
},
"tokenColors": [
{
"name": "plain",
"scope": ["source", "support.type.property-name.css"],
"settings": {
"foreground": "#100F0F"
}
},
{
"name": "classes",
"scope": ["entity.name.type.class"],
"settings": {
"foreground": "#BC5215"
}
},
{
"name": "interfaces",
"scope": ["entity.name.type.interface", "entity.name.type"],
"settings": {
"foreground": "#AD8301"
}
},
{
"name": "structs",
"scope": ["entity.name.type.struct"],
"settings": {
"foreground": "#BC5215"
}
},
{
"name": "enums",
"scope": ["entity.name.type.enum"],
"settings": {
"foreground": "#BC5215"
}
},
{
"name": "keys",
"scope": ["meta.object-literal.key", "support.type.property-name"],
"settings": {
"foreground": "#BC5215"
}
},
{
"name": "methods",
"scope": ["entity.name.function.method", "meta.function.method"],
"settings": {
"foreground": "#66800B"
}
},
{
"name": "functions",
"scope": [
"entity.name.function",
"support.function",
"meta.function-call.generic"
],
"settings": {
"foreground": "#BC5215",
"fontStyle": "bold"
}
},
{
"name": "variables",
"scope": ["variable", "meta.variable", "variable.other.object.property"],
"settings": {
"foreground": "#100F0F"
}
},
{
"name": "variablesOther",
"scope": ["variable.other.object", "variable.other.readwrite.alias"],
"settings": {
"foreground": "#66800B"
}
},
{
"name": "globalVariables",
"scope": ["variable.other.global", "variable.language.this"],
"settings": {
"foreground": "#A02F6F"
}
},
{
"name": "localVariables",
"scope": ["variable.other.local"],
"settings": {
"foreground": "#E6E4D9"
}
},
{
"name": "parameters",
"scope": ["variable.parameter", "meta.parameter"],
"settings": {
"foreground": "#100F0F"
}
},
{
"name": "properties",
"scope": ["variable.other.property", "meta.property"],
"settings": {
"foreground": "#205EA6"
}
},
{
"name": "strings",
"scope": [
"string",
"string.other.link",
"markup.inline.raw.string.markdown"
],
"settings": {
"foreground": "#24837B"
}
},
{
"name": "stringEscapeSequences",
"scope": ["constant.character.escape", "constant.other.placeholder"],
"settings": {
"foreground": "#100F0F"
}
},
{
"name": "keywords",
"scope": ["keyword"],
"settings": {
"foreground": "#66800B"
}
},
{
"name": "keywordsControl",
"scope": [
"keyword.control.import",
"keyword.control.from",
"keyword.import"
],
"settings": {
"foreground": "#AF3029"
}
},
{
"name": "storageModifiers",
"scope": ["storage.modifier", "keyword.modifier", "storage.type"],
"settings": {
"foreground": "#205EA6"
}
},
{
"name": "comments",
"scope": ["comment", "punctuation.definition.comment"],
"settings": {
"foreground": "#6F6E69"
}
},
{
"name": "docComments",
"scope": ["comment.documentation", "comment.line.documentation"],
"settings": {
"foreground": "#B7B5AC"
}
},
{
"name": "numbers",
"scope": ["constant.numeric"],
"settings": {
"foreground": "#5E409D"
}
},
{
"name": "booleans",
"scope": ["constant.language.boolean", "constant.language.json"],
"settings": {
"foreground": "#AD8301"
}
},
{
"name": "operators",
"scope": ["keyword.operator"],
"settings": {
"foreground": "#AF3029"
}
},
{
"name": "macros",
"scope": ["entity.name.function.preprocessor", "meta.preprocessor"],
"settings": {
"foreground": "#205EA6"
}
},
{
"name": "preprocessor",
"scope": ["meta.preprocessor"],
"settings": {
"foreground": "#A02F6F"
}
},
{
"name": "urls",
"scope": ["markup.underline.link"],
"settings": {
"foreground": "#205EA6"
}
},
{
"name": "tags",
"scope": ["entity.name.tag"],
"settings": {
"foreground": "#205EA6"
}
},
{
"name": "jsxTags",
"scope": ["support.class.component"],
"settings": {
"foreground": "#A02F6F"
}
},
{
"name": "attributes",
"scope": ["entity.other.attribute-name", "meta.attribute"],
"settings": {
"foreground": "#AD8301"
}
},
{
"name": "types",
"scope": ["support.type"],
"settings": {
"foreground": "#AD8301"
}
},
{
"name": "constants",
"scope": ["variable.other.constant", "variable.readonly"],
"settings": {
"foreground": "#100F0F"
}
},
{
"name": "labels",
"scope": ["entity.name.label", "punctuation.definition.label"],
"settings": {
"foreground": "#A02F6F"
}
},
{
"name": "namespaces",
"scope": [
"entity.name.namespace",
"storage.modifier.namespace",
"markup.bold.markdown"
],
"settings": {
"foreground": "#AD8301"
}
},
{
"name": "modules",
"scope": ["entity.name.module", "storage.modifier.module"],
"settings": {
"foreground": "#AF3029"
}
},
{
"name": "typeParameters",
"scope": ["variable.type.parameter", "variable.parameter.type"],
"settings": {
"foreground": "#BC5215"
}
},
{
"name": "exceptions",
"scope": ["keyword.control.exception", "keyword.control.trycatch"],
"settings": {
"foreground": "#A02F6F"
}
},
{
"name": "decorators",
"scope": [
"meta.decorator",
"punctuation.decorator",
"entity.name.function.decorator"
],
"settings": {
"foreground": "#AD8301"
}
},
{
"name": "calls",
"scope": ["variable.function"],
"settings": {
"foreground": "#100F0F"
}
},
{
"name": "punctuation",
"scope": [
"punctuation",
"punctuation.terminator",
"punctuation.definition.tag",
"punctuation.separator",
"punctuation.definition.string",
"punctuation.section.block"
],
"settings": {
"foreground": "#6F6E69"
}
},
{
"name": "yellow",
"scope": [
"storage.type.numeric.go",
"storage.type.byte.go",
"storage.type.boolean.go",
"storage.type.string.go",
"storage.type.uintptr.go",
"storage.type.error.go",
"storage.type.rune.go",
"constant.language.go",
"support.class.dart",
"keyword.other.documentation",
"storage.modifier.import.java",
"punctuation.definition.list.begin.markdown",
"punctuation.definition.quote.begin.markdown",
"meta.separator.markdown",
"entity.name.section.markdown"
],
"settings": {
"foreground": "#AD8301"
}
},
{
"name": "green",
"scope": [],
"settings": {
"foreground": "#66800B"
}
},
{
"name": "cyan",
"scope": [
"markup.italic.markdown",
"support.type.python",
"variable.legacy.builtin.python",
"support.constant.property-value.css",
"storage.modifier.attribute.swift"
],
"settings": {
"foreground": "#24837B"
}
},
{
"name": "blue",
"scope": [],
"settings": {
"foreground": "#205EA6"
}
},
{
"name": "purple",
"scope": ["keyword.channel.go", "keyword.other.platform.os.swift"],
"settings": {
"foreground": "#5E409D"
}
},
{
"name": "magenta",
"scope": ["punctuation.definition.heading.markdown"],
"settings": {
"foreground": "#A02F6F"
}
},
{
"name": "red",
"scope": [],
"settings": {
"foreground": "#AF3029"
}
},
{
"name": "orange",
"scope": [],
"settings": {
"foreground": "#BC5215"
}
}
]
}
+1 -1
View File
@@ -6,7 +6,7 @@ declare module 'streamdown' {
mode?: 'streaming' | 'static';
className?: string;
shikiTheme?: readonly [string, string] | [string, string];
shikiTheme?: readonly [string | object, string | object];
controls?: boolean | {
code?: boolean;