Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/extension-api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,14 @@ export interface HunkExtensionAPI {
readonly config: Record<string, unknown>;
/** Record a diagnostic line; collected per extension instead of written to the terminal. */
log(message: string): void;
/**
* Switch the active theme programmatically.
*
* Valid at any time — during the factory, from a lifecycle handler, or from
* a command handler. The theme id must match a built-in, config-defined, or
* extension-registered theme.
*/
setTheme(themeId: string): void;
}

/** Default export every extension entry file must provide. */
Expand Down
6 changes: 6 additions & 0 deletions src/extensions/runExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ export function createExtensionApi(
// Logs are collected rather than printed: the TUI owns the terminal.
registry.logs.push({ extensionId: metadata.id, message: String(message) });
},
setTheme(themeId: string) {
// Runtime action, not a registration — no assertOpen guard.
// The callback is bound after the UI mounts; before that, calls are a
// silent no-op since there is nothing to switch yet.
registry.setTheme?.(themeId);
},
};

return {
Expand Down
2 changes: 2 additions & 0 deletions src/extensions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ export interface ExtensionRegistry {
eventBusPhase: "loading" | "ready" | "closed";
/** Bound after loading so hunk.events.emit can dispatch at runtime. */
emitCustomEvent?: (event: string, payload: unknown) => void;
/** Bound after the UI mounts so hunk.setTheme can switch themes at runtime. */
setTheme?: (themeId: string) => void;
logs: ExtensionLogEntry[];
}

Expand Down
5 changes: 5 additions & 0 deletions src/ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,11 @@ export function App({
},
[showTransientNotice, themeOptions],
);
// Wire hunk.setTheme into the React theme state so extensions can switch
// themes programmatically at runtime.
if (extensions) {
extensions.registry.setTheme = selectTheme;
}

/** Open the keyboard-driven theme selector with the current theme highlighted. */
const openThemeSelector = useCallback(() => {
Expand Down