From 5328134d8103230cc5e450363632dc3019401908 Mon Sep 17 00:00:00 2001 From: Alex Bates Date: Wed, 25 Mar 2026 13:34:00 +0000 Subject: [PATCH] add Catppuccin theme and icons, default to Mocha/Latte based on system theme --- CLAUDE.md | 5 +++ app/package.json | 11 ++++- .../studio/src/browser/icon-theme-sync.ts | 40 +++++++++++++++++++ .../src/browser/studio-frontend-module.ts | 4 ++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 extensions/studio/src/browser/icon-theme-sync.ts diff --git a/CLAUDE.md b/CLAUDE.md index 55c5d5b..a3433ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -50,6 +50,11 @@ To reload the Electron window via CDP: echo '{"id":1,"method":"Page.reload","params":{}}' | websocat "$WS_URL" ``` +## Theia build gotchas + +- Changes to `theia.frontend.config` in `app/package.json` (e.g. `defaultTheme`, `defaultIconTheme`) require running `npx theia generate` inside `app/` to regenerate `src-gen/`. Watch mode doesn't do this. +- New plugins added to `theiaPlugins` require `yarn --cwd app download:plugins` and an app restart. + ## Theia/Monaco gotchas - `EditorManager.onCreated` fires when the widget is created, but the Monaco model may still be null. Use `monacoEditor.onDidChangeModel()` to wait for it. diff --git a/app/package.json b/app/package.json index 014cdb7..9afff72 100644 --- a/app/package.json +++ b/app/package.json @@ -29,7 +29,9 @@ "theiaPluginsDir": "../plugins", "theiaPlugins": { "vscode.cpp": "https://open-vsx.org/api/vscode/cpp/1.95.3/file/vscode.cpp-1.95.3.vsix", - "llvm-vs-code-extensions.vscode-clangd": "https://open-vsx.org/api/llvm-vs-code-extensions/vscode-clangd/0.4.0/file/llvm-vs-code-extensions.vscode-clangd-0.4.0.vsix" + "llvm-vs-code-extensions.vscode-clangd": "https://open-vsx.org/api/llvm-vs-code-extensions/vscode-clangd/0.4.0/file/llvm-vs-code-extensions.vscode-clangd-0.4.0.vsix", + "Catppuccin.catppuccin-vsc": "https://open-vsx.org/api/Catppuccin/catppuccin-vsc/3.18.1/file/Catppuccin.catppuccin-vsc-3.18.1.vsix", + "Catppuccin.catppuccin-vsc-icons": "https://open-vsx.org/api/Catppuccin/catppuccin-vsc-icons/1.26.0/file/Catppuccin.catppuccin-vsc-icons-1.26.0.vsix" }, "scripts": { "build": "theia build", @@ -45,7 +47,12 @@ "target": "electron", "frontend": { "config": { - "applicationName": "Star Haven Studio" + "applicationName": "Star Haven Studio", + "defaultTheme": { + "light": "Catppuccin Latte", + "dark": "Catppuccin Mocha" + }, + "defaultIconTheme": "catppuccin-mocha" } } } diff --git a/extensions/studio/src/browser/icon-theme-sync.ts b/extensions/studio/src/browser/icon-theme-sync.ts new file mode 100644 index 0000000..234cd00 --- /dev/null +++ b/extensions/studio/src/browser/icon-theme-sync.ts @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2026 Star Haven contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { + injectable, + inject, + postConstruct, +} from "@theia/core/shared/inversify"; +import { FrontendApplicationContribution } from "@theia/core/lib/browser"; +import { ThemeService } from "@theia/core/lib/browser/theming"; +import { IconThemeService } from "@theia/core/lib/browser/icon-theme-service"; + +const ICON_THEMES: Record = { + "Catppuccin Mocha": "catppuccin-mocha", + "Catppuccin Macchiato": "catppuccin-macchiato", + "Catppuccin Frappé": "catppuccin-frappe", + "Catppuccin Latte": "catppuccin-latte", +}; + +@injectable() +export class IconThemeSync implements FrontendApplicationContribution { + @inject(ThemeService) + protected readonly themeService!: ThemeService; + + @inject(IconThemeService) + protected readonly iconThemeService!: IconThemeService; + + @postConstruct() + protected init(): void { + this.themeService.onDidColorThemeChange(({ newTheme }) => { + const iconThemeId = ICON_THEMES[newTheme.id]; + if (iconThemeId) { + this.iconThemeService.current = iconThemeId; + } + }); + } + + async onStart(): Promise {} +} diff --git a/extensions/studio/src/browser/studio-frontend-module.ts b/extensions/studio/src/browser/studio-frontend-module.ts index a14bb08..c4ffe44 100644 --- a/extensions/studio/src/browser/studio-frontend-module.ts +++ b/extensions/studio/src/browser/studio-frontend-module.ts @@ -25,6 +25,7 @@ import { CommentFontDecorator } from "./comment-font-decorator"; import { CDeclarationService } from "./c-language/c-declaration-service"; import { DocCommentHoverContribution } from "./c-language/doc-comment-hover"; import { EvtCallInlayHintsContribution } from "./c-language/evt-call-inlay-hints"; +import { IconThemeSync } from "./icon-theme-sync"; import "../../src/browser/asset-browser/style.css"; import "../../src/browser/fonts/fonts.css"; @@ -65,4 +66,7 @@ export default new ContainerModule((bind) => { bind(FrontendApplicationContribution).toService( EvtCallInlayHintsContribution, ); + + bind(IconThemeSync).toSelf().inSingletonScope(); + bind(FrontendApplicationContribution).toService(IconThemeSync); }); -- 2.51.2