diff --git a/packages/cli/src/config/settings.ts b/packages/cli/src/config/settings.ts index 107ef522..1aabc127 100644 --- a/packages/cli/src/config/settings.ts +++ b/packages/cli/src/config/settings.ts @@ -9,6 +9,8 @@ import * as path from 'path'; import { homedir } from 'os'; import { MCPServerConfig } from '@gemini-code/core/src/config/config.js'; import stripJsonComments from 'strip-json-comments'; +import { DefaultLight } from '../ui/themes/default-light.js'; +import { DefaultDark } from '../ui/themes/default.js'; export const SETTINGS_DIRECTORY_NAME = '.gemini'; export const USER_SETTINGS_DIR = path.join(homedir(), SETTINGS_DIRECTORY_NAME); @@ -88,13 +90,19 @@ export class LoadedSettings { */ export function loadSettings(workspaceDir: string): LoadedSettings { let userSettings: Settings = {}; - let workspaceSettings = {}; + let workspaceSettings: Settings = {}; // Load user settings try { if (fs.existsSync(USER_SETTINGS_PATH)) { const userContent = fs.readFileSync(USER_SETTINGS_PATH, 'utf-8'); - userSettings = JSON.parse(stripJsonComments(userContent)); + userSettings = JSON.parse(stripJsonComments(userContent)) as Settings; + // Support legacy theme names + if (userSettings.theme && userSettings.theme === 'VS') { + userSettings.theme = DefaultLight.name; + } else if (userSettings.theme && userSettings.theme === 'VS2015') { + userSettings.theme = DefaultDark.name; + } } } catch (error) { console.error('Error reading user settings file:', error); @@ -110,7 +118,17 @@ export function loadSettings(workspaceDir: string): LoadedSettings { try { if (fs.existsSync(workspaceSettingsPath)) { const projectContent = fs.readFileSync(workspaceSettingsPath, 'utf-8'); - workspaceSettings = JSON.parse(stripJsonComments(projectContent)); + workspaceSettings = JSON.parse( + stripJsonComments(projectContent), + ) as Settings; + if (workspaceSettings.theme && workspaceSettings.theme === 'VS') { + workspaceSettings.theme = DefaultLight.name; + } else if ( + workspaceSettings.theme && + workspaceSettings.theme === 'VS2015' + ) { + workspaceSettings.theme = DefaultDark.name; + } } } catch (error) { console.error('Error reading workspace settings file:', error); diff --git a/packages/cli/src/ui/themes/ansi-light.ts b/packages/cli/src/ui/themes/ansi-light.ts new file mode 100644 index 00000000..dae9eecd --- /dev/null +++ b/packages/cli/src/ui/themes/ansi-light.ts @@ -0,0 +1,130 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { lightTheme, Theme } from './theme.js'; + +export const ANSILight: Theme = new Theme( + 'ANSI Light', + 'light', + { + hljs: { + display: 'block', + overflowX: 'auto', + padding: '0.5em', + background: 'white', + color: 'black', + }, + 'hljs-keyword': { + color: 'blue', + }, + 'hljs-literal': { + color: 'blue', + }, + 'hljs-symbol': { + color: 'blue', + }, + 'hljs-name': { + color: 'blue', + }, + 'hljs-link': { + color: 'blue', + }, + 'hljs-built_in': { + color: 'cyan', + }, + 'hljs-type': { + color: 'cyan', + }, + 'hljs-number': { + color: 'green', + }, + 'hljs-class': { + color: 'green', + }, + 'hljs-string': { + color: 'red', + }, + 'hljs-meta-string': { + color: 'red', + }, + 'hljs-regexp': { + color: 'magenta', + }, + 'hljs-template-tag': { + color: 'magenta', + }, + 'hljs-subst': { + color: 'black', + }, + 'hljs-function': { + color: 'black', + }, + 'hljs-title': { + color: 'black', + }, + 'hljs-params': { + color: 'black', + }, + 'hljs-formula': { + color: 'black', + }, + 'hljs-comment': { + color: 'gray', + }, + 'hljs-quote': { + color: 'gray', + }, + 'hljs-doctag': { + color: 'gray', + }, + 'hljs-meta': { + color: 'gray', + }, + 'hljs-meta-keyword': { + color: 'gray', + }, + 'hljs-tag': { + color: 'gray', + }, + 'hljs-variable': { + color: 'purple', + }, + 'hljs-template-variable': { + color: 'purple', + }, + 'hljs-attr': { + color: 'blue', + }, + 'hljs-attribute': { + color: 'blue', + }, + 'hljs-builtin-name': { + color: 'blue', + }, + 'hljs-section': { + color: 'orange', + }, + 'hljs-bullet': { + color: 'orange', + }, + 'hljs-selector-tag': { + color: 'orange', + }, + 'hljs-selector-id': { + color: 'orange', + }, + 'hljs-selector-class': { + color: 'orange', + }, + 'hljs-selector-attr': { + color: 'orange', + }, + 'hljs-selector-pseudo': { + color: 'orange', + }, + }, + lightTheme, +); diff --git a/packages/cli/src/ui/themes/ansi.ts b/packages/cli/src/ui/themes/ansi.ts index b5e2015e..bfc43495 100644 --- a/packages/cli/src/ui/themes/ansi.ts +++ b/packages/cli/src/ui/themes/ansi.ts @@ -4,11 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { ansiTheme, Theme } from './theme.js'; +import { darkTheme, Theme } from './theme.js'; export const ANSI: Theme = new Theme( 'ANSI', - 'ansi', + 'dark', { hljs: { display: 'block', @@ -135,5 +135,5 @@ export const ANSI: Theme = new Theme( color: 'yellow', // Mapped from #D7BA7D }, }, - ansiTheme, + darkTheme, ); diff --git a/packages/cli/src/ui/themes/vs.ts b/packages/cli/src/ui/themes/default-light.ts similarity index 96% rename from packages/cli/src/ui/themes/vs.ts rename to packages/cli/src/ui/themes/default-light.ts index 2faf02a7..b86af6f3 100644 --- a/packages/cli/src/ui/themes/vs.ts +++ b/packages/cli/src/ui/themes/default-light.ts @@ -6,8 +6,8 @@ import { lightTheme, Theme } from './theme.js'; -export const VS: Theme = new Theme( - 'VS', +export const DefaultLight: Theme = new Theme( + 'Default Light', 'light', { hljs: { diff --git a/packages/cli/src/ui/themes/vs2015.ts b/packages/cli/src/ui/themes/default.ts similarity index 97% rename from packages/cli/src/ui/themes/vs2015.ts rename to packages/cli/src/ui/themes/default.ts index 34431abf..f3c8cbcd 100644 --- a/packages/cli/src/ui/themes/vs2015.ts +++ b/packages/cli/src/ui/themes/default.ts @@ -6,8 +6,8 @@ import { darkTheme, Theme } from './theme.js'; -export const VS2015: Theme = new Theme( - 'VS2015', +export const DefaultDark: Theme = new Theme( + 'Default', 'dark', { hljs: { diff --git a/packages/cli/src/ui/themes/theme-manager.ts b/packages/cli/src/ui/themes/theme-manager.ts index e17fa5b7..2b12a4c1 100644 --- a/packages/cli/src/ui/themes/theme-manager.ts +++ b/packages/cli/src/ui/themes/theme-manager.ts @@ -8,18 +8,19 @@ import { AtomOneDark } from './atom-one-dark.js'; import { Dracula } from './dracula.js'; import { GitHub } from './github.js'; import { GoogleCode } from './googlecode.js'; -import { VS } from './vs.js'; -import { VS2015 } from './vs2015.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'; export interface ThemeDisplay { name: string; type: ThemeType; } -export const DEFAULT_THEME: Theme = VS2015; +export const DEFAULT_THEME: Theme = DefaultDark; class ThemeManager { private readonly availableThemes: Theme[]; @@ -29,12 +30,13 @@ class ThemeManager { this.availableThemes = [ AtomOneDark, Dracula, - VS, // Light mode. - VS2015, + DefaultLight, // Light mode. + DefaultDark, GitHub, GoogleCode, XCode, ANSI, + ANSILight, ]; this.activeTheme = DEFAULT_THEME; } @@ -50,10 +52,8 @@ class ThemeManager { return 1; case 'light': return 2; - case 'ansi': - return 3; default: - return 4; + return 3; } }; diff --git a/packages/cli/src/ui/themes/theme.ts b/packages/cli/src/ui/themes/theme.ts index 582d2e9e..abe9b101 100644 --- a/packages/cli/src/ui/themes/theme.ts +++ b/packages/cli/src/ui/themes/theme.ts @@ -63,7 +63,7 @@ export const ansiTheme: ColorsTheme = { LightBlue: 'blue', AccentBlue: 'blue', AccentPurple: 'magenta', - AccentCyan: 'cynan', + AccentCyan: 'cyan', AccentGreen: 'green', AccentYellow: 'yellow', AccentRed: 'red',