gemini-cli/packages/cli/src/ui/themes/theme-manager.ts

124 lines
3.1 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { AyuDark } from './ayu.js';
import { AyuLight } from './ayu-light.js';
import { AtomOneDark } from './atom-one-dark.js';
import { Dracula } from './dracula.js';
import { GitHubDark } from './github-dark.js';
import { GitHubLight } from './github-light.js';
import { GoogleCode } from './googlecode.js';
import { DefaultLight } from './default-light.js';
import { DefaultDark } from './default.js';
import { XCode } from './xcode.js';
import { Theme, ThemeType } from './theme.js';
import { ANSI } from './ansi.js';
import { ANSILight } from './ansi-light.js';
import { NoColorTheme } from './no-color.js';
import process from 'node:process';
export interface ThemeDisplay {
name: string;
type: ThemeType;
}
export const DEFAULT_THEME: Theme = DefaultDark;
class ThemeManager {
private readonly availableThemes: Theme[];
private activeTheme: Theme;
constructor() {
this.availableThemes = [
AyuDark,
AyuLight,
AtomOneDark,
Dracula,
DefaultLight,
DefaultDark,
GitHubDark,
GitHubLight,
GoogleCode,
XCode,
ANSI,
ANSILight,
];
this.activeTheme = DEFAULT_THEME;
}
/**
* Returns a list of available theme names.
*/
getAvailableThemes(): ThemeDisplay[] {
const sortedThemes = [...this.availableThemes].sort((a, b) => {
const typeOrder = (type: ThemeType): number => {
switch (type) {
case 'dark':
return 1;
case 'light':
return 2;
default:
return 3;
}
};
const typeComparison = typeOrder(a.type) - typeOrder(b.type);
if (typeComparison !== 0) {
return typeComparison;
}
return a.name.localeCompare(b.name);
});
return sortedThemes.map((theme) => ({
name: theme.name,
type: theme.type,
}));
}
/**
* Sets the active theme.
* @param themeName The name of the theme to activate.
* @returns True if the theme was successfully set, false otherwise.
*/
setActiveTheme(themeName: string | undefined): boolean {
const foundTheme = this.findThemeByName(themeName);
if (foundTheme) {
this.activeTheme = foundTheme;
return true;
} else {
// If themeName is undefined, it means we want to set the default theme.
// If findThemeByName returns undefined (e.g. default theme is also not found for some reason)
// then this will return false.
if (themeName === undefined) {
this.activeTheme = DEFAULT_THEME;
return true;
}
return false;
}
}
findThemeByName(themeName: string | undefined): Theme | undefined {
if (!themeName) {
return DEFAULT_THEME;
}
return this.availableThemes.find((theme) => theme.name === themeName);
}
/**
* Returns the currently active theme object.
*/
getActiveTheme(): Theme {
if (process.env.NO_COLOR) {
return NoColorTheme;
}
return this.activeTheme;
}
}
// Export an instance of the ThemeManager
export const themeManager = new ThemeManager();