From 82241c8c49b340dbea54c427eaad3fb5b4fc6ce3 Mon Sep 17 00:00:00 2001 From: BeardedBear Date: Tue, 20 Jan 2026 12:20:40 +0100 Subject: [PATCH 1/9] Add JetBrains theme generator --- .gitignore | 2 +- AGENTS.md | 157 +++- META-INF/plugin.xml | 81 ++ bearded-theme-arc.theme.json | 558 +++++++++++ bearded-theme-arc.xml | 1046 +++++++++++++++++++++ bearded-theme-black-&-ruby.xml | 1045 ++++++++++++++++++++ package.json | 15 +- src/build.ts | 153 ++- src/generators/jetbrains/README.md | 190 ++++ src/generators/jetbrains/editor-scheme.ts | 594 ++++++++++++ src/generators/jetbrains/index.ts | 605 ++++++++++++ src/generators/jetbrains/plugin.ts | 135 +++ src/generators/jetbrains/theme.ts | 107 +++ src/generators/jetbrains/types.ts | 793 ++++++++++++++++ src/generators/jetbrains/ui.ts | 732 ++++++++++++++ src/generators/jetbrains/utils.ts | 173 ++++ src/version-manager.ts | 10 + versions.json | 3 +- 18 files changed, 6371 insertions(+), 28 deletions(-) create mode 100644 META-INF/plugin.xml create mode 100644 bearded-theme-arc.theme.json create mode 100644 bearded-theme-arc.xml create mode 100644 bearded-theme-black-&-ruby.xml create mode 100644 src/generators/jetbrains/README.md create mode 100644 src/generators/jetbrains/editor-scheme.ts create mode 100644 src/generators/jetbrains/index.ts create mode 100644 src/generators/jetbrains/plugin.ts create mode 100644 src/generators/jetbrains/theme.ts create mode 100644 src/generators/jetbrains/types.ts create mode 100644 src/generators/jetbrains/ui.ts create mode 100644 src/generators/jetbrains/utils.ts diff --git a/.gitignore b/.gitignore index 82c80cc..cbec71b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ node_modules *.vsix *.zip .env -dist/vscode +dist diff --git a/AGENTS.md b/AGENTS.md index 7a1dad0..0fd4569 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ This document provides guidelines and best practices for AI agents working on th ## Project Overview -Bearded Theme is a color theme extension for **VS Code** and **Zed** editors. It features 60+ theme variants including dark, light, high-contrast, and accessibility-focused options. +Bearded Theme is a color theme extension for **VS Code**, **Zed**, and **JetBrains IDEs** (WebStorm, IntelliJ IDEA, PyCharm, PhpStorm, GoLand, Rider, etc.). It features 60+ theme variants including dark, light, high-contrast, and accessibility-focused options. ### Key Technologies @@ -33,13 +33,33 @@ bearded-theme/ │ │ │ ├── prog.ts │ │ │ ├── markup.ts │ │ │ └── styling.ts -│ │ └── zed/ # Zed theme generator +│ │ ├── zed/ # Zed theme generator +│ │ │ ├── index.ts # Zed build script +│ │ │ ├── types.ts # Zed specific type definitions +│ │ │ ├── ui.ts # Zed UI color mappings +│ │ │ └── syntax.ts # Zed syntax highlighting +│ │ └── jetbrains/ # JetBrains theme generator +│ │ ├── index.ts # JetBrains build script (generates full plugin) +│ │ ├── ui.ts # JetBrains UI color mappings +│ │ ├── types.ts # JetBrains specific type definitions +│ │ ├── theme.ts # Theme JSON builder +│ │ ├── editor-scheme.ts # Editor color scheme XML generator +│ │ ├── plugin.ts # Plugin manifest (plugin.xml) generator +│ │ ├── utils.ts # Color utility functions +│ │ └── README.md # Installation instructions │ ├── variations/ # Theme color definitions (shared) │ ├── helper.ts # Color utility functions │ └── build.ts # Build orchestrator ├── dist/ # Generated output (DO NOT edit manually) │ ├── vscode/themes/ -│ └── zed/themes/ +│ ├── zed/themes/ +│ └── jetbrains/ # Complete JetBrains plugin structure +│ ├── resources/META-INF/plugin.xml # Plugin manifest +│ ├── themes/*.theme.json # UI theme files +│ ├── themes/*.xml # Editor color schemes +│ ├── build.gradle.kts # Gradle build file +│ ├── settings.gradle.kts # Gradle settings +│ └── gradle.properties # Gradle properties ├── releases/ # VSIX packages and release notes └── assets/ # Icons and images ``` @@ -51,10 +71,12 @@ bearded-theme/ | `src/shared/theme-registry.ts` | **Single source of truth** for all theme variants | | `src/shared/types.ts` | Shared TypeScript interfaces (Theme, ThemeColors, ThemeUi, etc.) | | `src/generators/vscode/types.ts` | VS Code specific type definitions (ActivityBarColors, EditorColors, etc.) | +| `src/generators/jetbrains/types.ts` | JetBrains specific type definitions (JetBrainsTheme, JetBrainsUiColors) | | `src/helper.ts` | Color manipulation utilities (`makeMainColorsDark`, `makeMainColorsLight`) | | `src/variations/*.ts` | Individual theme color palettes | | `src/generators/vscode/ui.ts` | VS Code UI color mappings | | `src/generators/vscode/scopes/*.ts` | VS Code syntax highlighting scopes | +| `src/generators/jetbrains/ui.ts` | JetBrains UI color mappings | | `package.json` | Extension manifest with theme contributions | ## Coding Standards @@ -246,32 +268,128 @@ interface ThemeOptions { - `styling.ts` - CSS/SCSS tokens - `semanticTokens.ts` - Semantic token colors -- **Zed**: Edit `buildSyntax()` function in `src/generators/zed/index.ts` +- **Zed**: Edit `buildSyntax()` function in `src/generators/zed/syntax.ts` + +- **JetBrains**: Edit `buildAttributeOptions()` in `src/generators/jetbrains/editor-scheme.ts` ### Modifying UI Colors - **VS Code**: Edit `src/generators/vscode/ui.ts` -- **Zed**: Edit `buildZedThemeStyle()` in `src/generators/zed/index.ts` +- **Zed**: Edit `buildZedThemeStyle()` in `src/generators/zed/ui.ts` +- **JetBrains**: Edit `src/generators/jetbrains/ui.ts` ## Build Commands -| Command | Description | -| ---------------------- | ------------------------------------ | -| `npm run build` | Build all themes (VS Code + Zed) | -| `npm run build:vscode` | Build VS Code themes only | -| `npm run build:zed` | Build Zed themes only | -| `npm run dev:vscode` | Watch mode for VS Code | -| `npm run dev:zed` | Watch mode for Zed | -| `npm run lint` | Check code with ESLint (no auto-fix) | -| `npm run fix` | Format and fix code with ESLint | +| Command | Description | +| --------------------------------- | ------------------------------------------------------- | +| `npm run clean` | Clean all dist folders | +| `npm run clean:vscode` | Clean dist/vscode folder only | +| `npm run clean:zed` | Clean dist/zed folder only | +| `npm run clean:jetbrains` | Clean dist/jetbrains folder only | +| `npm run build` | Build all themes + JetBrains plugin (requires Java 11+) | +| `npm run build:vscode` | Build VS Code themes only (auto-cleans first) | +| `npm run build:zed` | Build Zed themes only (auto-cleans first) | +| `npm run build:jetbrains` | Build JetBrains themes only (auto-cleans first) | +| `npm run build:ext:jetbrains` | Build JetBrains plugin package (requires Java 11+) | +| `npm run install:jetbrains:local` | Install JetBrains themes to local IDE (for testing) | +| `npm run dev:jetbrains:install` | Build + install JetBrains themes in one command | +| `npm run dev:vscode` | Watch mode for VS Code | +| `npm run dev:zed` | Watch mode for Zed | +| `npm run dev:jetbrains` | Watch mode for JetBrains | +| `npm run lint` | Check code with ESLint (no auto-fix) | +| `npm run fix` | Format and fix code with ESLint | + +### JetBrains Plugin Build + +The main `npm run build` command will: + +1. Build all VS Code, Zed, and JetBrains themes +2. Download the Gradle wrapper automatically +3. Attempt to build the JetBrains plugin package (`.zip` file) + +**Requirements for plugin build:** + +- Java 11 or higher (download from [adoptium.net](https://adoptium.net/)) +- If Java is not installed, the build will skip the plugin packaging step but still succeed +- Theme files will still be generated and can be installed manually + +**To build the plugin manually:** + +```bash +npm run build:ext:jetbrains +``` + +### JetBrains Editor Color Schemes - IMPORTANT + +**Critical: Always use the official JetBrains method for editor schemes to avoid IDE crashes.** + +Per [official JetBrains documentation](https://plugins.jetbrains.com/docs/intellij/themes-extras.html#adding-a-custom-editor-scheme): + +#### ✅ Correct Method (Currently Used) + +1. **File Extension**: Generate editor schemes as `.xml` files (not `.icls`) + - While IDEs export schemes as `.icls`, they must be renamed to `.xml` for bundling +2. **Reference Location**: Reference schemes **ONLY** in `.theme.json` files: + + ```json + { + "name": "My Theme", + "editorScheme": "/my-theme.xml", + "ui": { ... } + } + ``` + +3. **NO plugin.xml Declaration**: Do NOT use `` in `plugin.xml` + - This causes `NullPointerException` crashes in WebStorm and other IDEs + +4. **Color Format**: Always use 6-digit hex RGB (e.g., `0187A6`) without `#` prefix + - Pre-mix alpha transparency using `colord().mix()` before generating values + +#### ❌ Incorrect Method (DO NOT USE) + +```xml + + + + +``` + +```json +// my-theme.theme.json - WRONG EXTENSION +{ + "editorScheme": "/themes/my-theme.icls" // ❌ WRONG +} +``` + +#### Implementation Files + +- **Generator**: `src/generators/jetbrains/editor-scheme.ts` - Generates `.xml` files +- **Theme Builder**: `src/generators/jetbrains/theme.ts` - References schemes in JSON +- **Color Utility**: `src/generators/jetbrains/utils.ts` - `toHex()` function + +#### Testing Editor Schemes + +After modifying editor scheme generation: + +1. Build: `npm run build:jetbrains` +2. Verify `.xml` files exist: `ls dist/jetbrains/themes/*.xml` +3. Check theme JSON references: `grep editorScheme dist/jetbrains/themes/*.theme.json` +4. Confirm NO bundledColorScheme: `grep bundledColorScheme dist/jetbrains/resources/META-INF/plugin.xml` +5. Install and test: `npm run install:jetbrains:local` +6. Restart IDE and verify no crashes + +**See `JETBRAINS-EDITOR-SCHEMES-FIX.md` for detailed troubleshooting history.** ## Testing Guidelines -1. **Always run build after changes**: `npm run build` +1. **Always run build after changes**: `npm run build` (automatically cleans dist folder and builds plugin) 2. **Test in VS Code**: Press F5 to launch Extension Development Host -3. **Test multiple themes**: Check at least one dark, one light, and one HC theme -4. **Check syntax highlighting**: Open files in JS, TS, Python, Markdown, CSS -5. **Verify UI elements**: Sidebar, tabs, status bar, panels, notifications +3. **Test in JetBrains**: + - For quick testing: Run `npm run install:jetbrains:local` and restart IDE + - For plugin testing: Install the built `.zip` from `dist/jetbrains/build/distributions/` +4. **Test multiple themes**: Check at least one dark, one light, and one HC theme +5. **Check syntax highlighting**: Open files in JS, TS, Python, Markdown, CSS +6. **Verify UI elements**: Sidebar, tabs, status bar, panels, notifications ## Do's and Don'ts @@ -281,7 +399,7 @@ interface ThemeOptions { - ✅ Follow the established pattern when creating new themes - ✅ Register new themes in `theme-registry.ts` (single source of truth) - ✅ Run `npm run fix` before committing (uses ESLint Stylistic) -- ✅ Test both VS Code and Zed output when modifying shared code +- ✅ Test VS Code, Zed, and JetBrains output when modifying shared code - ✅ Use meaningful, descriptive theme names - ✅ Maintain color accessibility (contrast ratios) @@ -293,6 +411,7 @@ interface ThemeOptions { - ❌ Don't use RGB/HSL directly - always use hex with colord conversions - ❌ Don't break existing theme slugs (used as identifiers) - ❌ Don't create new documentation files (README.md, CONTRIBUTING.md, etc.) unless explicitly requested +- ❌ Don't use unsupported JetBrains color keys (check IntelliJ Platform SDK docs) ## Accessibility Considerations diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml new file mode 100644 index 0000000..115bed5 --- /dev/null +++ b/META-INF/plugin.xml @@ -0,0 +1,81 @@ + + + com.beardedtheme.jetbrains + Bearded Theme + 1.0.0 + BeardedBear + + + + com.intellij.modules.platform + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bearded-theme-arc.theme.json b/bearded-theme-arc.theme.json new file mode 100644 index 0000000..fd96df8 --- /dev/null +++ b/bearded-theme-arc.theme.json @@ -0,0 +1,558 @@ +{ + "author": "BeardedBear", + "colors": { + "background": "#1c2433", + "backgroundAlt": "#181f2c", + "backgroundMid": "#1a212f", + "blue": "#69C3FF", + "border": "#11161f", + "danger": "#E35535", + "foreground": "#d0d7e4", + "foregroundAlt": "#4a5e84", + "foregroundMain": "#afbbd2", + "green": "#3CEC85", + "greenAlt": "#A4EF58", + "info": "#69C3FF", + "orange": "#FF955C", + "pink": "#F38CEC", + "primary": "#8196b5", + "primaryAlt": "#253043", + "purple": "#B78AFF", + "red": "#E35535", + "salmon": "#FF738A", + "success": "#3CEC85", + "turquoize": "#22ECDB", + "warning": "#FF955C", + "yellow": "#EACD61" + }, + "dark": true, + "editorScheme": "/bearded-theme-arc.xml", + "name": "Bearded Theme Arc", + "parentTheme": "Islands Dark", + "ui": { + "*": { + "acceleratorForeground": "#4a5e84", + "acceleratorSelectionForeground": "#d0d7e4", + "background": "#1c2433", + "borderColor": "#11161f", + "caretForeground": "#8196b5", + "disabledBackground": "#1c243399", + "disabledBorderColor": "#11161f80", + "disabledForeground": "#d0d7e466", + "disabledText": "#d0d7e466", + "errorBorderColor": "#E35535", + "errorForeground": "#E35535", + "focusColor": "#8196b580", + "focusedBorderColor": "#8196b5", + "foreground": "#d0d7e4", + "hoverBackground": "#253043", + "hoverBorderColor": "#232d40", + "inactiveBackground": "#181f2c", + "inactiveForeground": "#4a5e84", + "infoForeground": "#69C3FF", + "lightSelectionBackground": "#8196b526", + "lightSelectionForeground": "#d0d7e4", + "modifiedItemForeground": "#69C3FF", + "pressedBackground": "#8196b54d", + "pressedBorderColor": "#8196b5", + "selectionBackground": "#8196b533", + "selectionForeground": "#d0d7e4", + "selectionInactiveBackground": "#8196b51a", + "selectionInactiveForeground": "#d0d7e4", + "separatorColor": "#11161f", + "warningBorderColor": "#FF955C", + "warningForeground": "#FF955C" + }, + "ActionButton.hoverBackground": "#253043", + "ActionButton.hoverBorderColor": "#11161F00", + "ActionButton.pressedBackground": "#8196b54d", + "ActionButton.pressedBorderColor": "#11161F00", + "Banner.errorBackground": "#e3553526", + "Banner.errorBorderColor": "#e3553580", + "Banner.infoBackground": "#69c3ff26", + "Banner.infoBorderColor": "#69c3ff80", + "Banner.successBackground": "#3cec8526", + "Banner.successBorderColor": "#3cec8580", + "Banner.warningBackground": "#ff955c26", + "Banner.warningBorderColor": "#ff955c80", + "Borders.color": "#11161f", + "Borders.ContrastBorderColor": "#232d40", + "Button.arc": 6, + "Button.default.endBackground": "#8196b5", + "Button.default.focusColor": "#8196b580", + "Button.default.focusedBorderColor": "#c1ccdb", + "Button.default.foreground": "#000000", + "Button.default.shadowColor": "#1C243300", + "Button.default.startBackground": "#8196b5", + "Button.disabledText": "#d0d7e466", + "Button.endBackground": "#181f2c", + "Button.focusedBorderColor": "#8196b5", + "Button.foreground": "#d0d7e4", + "Button.shadowColor": "#1C243300", + "Button.startBackground": "#181f2c", + "Checkbox.Background.Default": "#212b3d", + "Checkbox.Background.Disabled": "#212b3d80", + "Checkbox.Background.Selected": "#8196b5", + "Checkbox.Border.Default": "#11161f", + "Checkbox.Border.Disabled": "#11161f80", + "Checkbox.Border.Selected": "#8196b5", + "Checkbox.Focus.Thin.Default": "#8196b580", + "Checkbox.Focus.Thin.Selected": "#8196b580", + "Checkbox.Focus.Wide": "#8196b54d", + "Checkbox.Foreground.Disabled": "#d0d7e466", + "Checkbox.Foreground.Selected": "#000000", + "ComboBox.ArrowButton.background": "#212b3d", + "ComboBox.ArrowButton.disabledIconColor": "#d0d7e44d", + "ComboBox.ArrowButton.iconColor": "#4a5e84", + "ComboBox.ArrowButton.nonEditableBackground": "#212b3d", + "ComboBox.background": "#212b3d", + "ComboBox.disabledBackground": "#212b3d80", + "ComboBox.disabledForeground": "#d0d7e466", + "ComboBox.foreground": "#d0d7e4", + "ComboBox.modifiedItemForeground": "#69C3FF", + "ComboBox.nonEditableBackground": "#212b3d", + "ComboBox.selectionBackground": "#8196b533", + "ComboBox.selectionForeground": "#d0d7e4", + "CompletionPopup.background": "#1a212f", + "CompletionPopup.foreground": "#d0d7e4", + "CompletionPopup.matchForeground": "#8196b5", + "CompletionPopup.selectionBackground": "#8196b533", + "CompletionPopup.selectionForeground": "#d0d7e4", + "CompletionPopup.selectionInactiveBackground": "#8196b51a", + "CompletionPopup.selectionInfoForeground": "#4a5e84", + "Counter.background": "#8196b5", + "Counter.foreground": "#000000", + "Debugger.Variables.collectingDataForeground": "#4a5e84", + "Debugger.Variables.errorMessageForeground": "#E35535", + "Debugger.Variables.evaluatingExpressionForeground": "#69C3FF", + "Debugger.Variables.modifyingValueForeground": "#FF955C", + "Debugger.Variables.type": "#B78AFF", + "DefaultTabs.background": "#181f2c", + "DefaultTabs.borderColor": "#11161f", + "DefaultTabs.hoverBackground": "#253043", + "DefaultTabs.inactiveColoredFileBackground": "#1C243300", + "DefaultTabs.inactiveMaskColor": "#1C243300", + "DefaultTabs.underlineColor": "#8196b5", + "DefaultTabs.underlinedTabBackground": "#1c2433", + "DefaultTabs.underlinedTabForeground": "#d0d7e4", + "DefaultTabs.underlineHeight": 3, + "DragAndDrop.areaBackground": "#8196b51a", + "DragAndDrop.areaBorderColor": "#8196b5", + "DragAndDrop.areaForeground": "#8196b5", + "Editor.background": "#1c2433", + "Editor.foreground": "#d0d7e4", + "Editor.SearchField.background": "#212b3d", + "EditorPane.background": "#1c2433", + "EditorTabs.background": "#181f2c", + "EditorTabs.borderColor": "#11161f", + "EditorTabs.hoverBackground": "#253043", + "EditorTabs.inactiveColoredFileBackground": "#1C243300", + "EditorTabs.inactiveMaskColor": "#1C243300", + "EditorTabs.inactiveUnderlineColor": "#8196b580", + "EditorTabs.inactiveUnderlinedTabBackground": "#1a212f", + "EditorTabs.inactiveUnderlinedTabBorderColor": "#8196b580", + "EditorTabs.underlineArc": 0, + "EditorTabs.underlineColor": "#8196b5", + "EditorTabs.underlinedBorderColor": "#8196b5", + "EditorTabs.underlinedTabBackground": "#1c2433", + "EditorTabs.underlinedTabForeground": "#d0d7e4", + "EditorTabs.underlineHeight": 3, + "FileColor.Blue": "#69c3ff26", + "FileColor.Green": "#3cec8526", + "FileColor.Orange": "#ff955c26", + "FileColor.Rose": "#f38cec26", + "FileColor.Violet": "#b78aff26", + "FileColor.Yellow": "#eacd6126", + "Focus.borderColor": "#8196b5", + "Focus.color": "#8196b580", + "Git.Log.Ref.LocalBranch": "#3CEC85", + "Git.Log.Ref.Other": "#B78AFF", + "Git.Log.Ref.RemoteBranch": "#22ECDB", + "Git.Log.Ref.Tag": "#EACD61", + "Group.disabledSeparatorColor": "#11161f80", + "Group.separatorColor": "#11161f", + "GutterTooltip.backgroundColor": "#1a212f", + "GutterTooltip.borderColor": "#11161f", + "GutterTooltip.lineSeparatorColor": "#11161f", + "InfoPanel.background": "#181f2c", + "InfoPanel.foreground": "#d0d7e4", + "InplaceRefactoringPopup.borderColor": "#8196b5", + "Island.arc": 20, + "Island.arc.compact": 16, + "Island.borderColor": "#1c2433", + "Island.borderWidth": 5, + "Island.borderWidth.compact": 4, + "Island.inactiveAlpha": 0.44, + "Islands": 1, + "Label.background": "#1c2433", + "Label.disabledForeground": "#d0d7e466", + "Label.errorForeground": "#E35535", + "Label.foreground": "#d0d7e4", + "Label.infoForeground": "#69C3FF", + "Label.selectedDisabledForeground": "#d0d7e466", + "Label.selectedForeground": "#d0d7e4", + "Label.successForeground": "#3CEC85", + "Label.warningForeground": "#FF955C", + "Link.activeForeground": "#a1b1c8", + "Link.hoverForeground": "#a1b1c8", + "Link.pressedForeground": "#617ba2", + "Link.secondaryForeground": "#4a5e84", + "Link.visitedForeground": "#B78AFF", + "List.background": "#1c2433", + "List.foreground": "#d0d7e4", + "List.hoverBackground": "#253043", + "List.selectionBackground": "#8196b533", + "List.selectionForeground": "#d0d7e4", + "List.selectionInactiveBackground": "#8196b51a", + "List.selectionInactiveForeground": "#d0d7e4", + "MainMenu.background": "#181f2c", + "MainMenu.borderColor": "#11161f", + "MainMenu.disabledForeground": "#d0d7e466", + "MainMenu.foreground": "#d0d7e4", + "MainMenu.selectionBackground": "#8196b533", + "MainMenu.selectionForeground": "#d0d7e4", + "MainToolbar.background": "#181f2c", + "MainToolbar.borderColor": "#11161F00", + "MainToolbar.Dropdown.background": "#181f2c", + "MainToolbar.Dropdown.hoverBackground": "#253043", + "MainToolbar.Icon.hoverBackground": "#253043", + "MainToolbar.Icon.pressedBackground": "#8196b54d", + "MainToolbar.inactiveBackground": "#181f2c", + "MainToolbar.separatorColor": "#11161f", + "MainWindow.background": "#212b3d", + "MainWindow.Tab.background": "#181f2c", + "MainWindow.Tab.foreground": "#4a5e84", + "MainWindow.Tab.hoverBackground": "#253043", + "MainWindow.Tab.inactiveUnderlineColor": "#8196b580", + "MainWindow.Tab.selectedBackground": "#1c2433", + "MainWindow.Tab.underlineColor": "#8196b5", + "MainWindow.Tab.underlineHeight": 3, + "MemoryIndicator.allocatedBackground": "#8196b533", + "MemoryIndicator.usedBackground": "#8196b5", + "Menu.acceleratorForeground": "#4a5e84", + "Menu.acceleratorSelectionForeground": "#d0d7e4", + "Menu.background": "#1a212f", + "Menu.borderColor": "#11161f", + "Menu.disabledForeground": "#d0d7e466", + "Menu.foreground": "#d0d7e4", + "Menu.selectionBackground": "#8196b533", + "Menu.selectionForeground": "#d0d7e4", + "Menu.separatorColor": "#11161f", + "MenuItem.acceleratorForeground": "#4a5e84", + "MenuItem.acceleratorSelectionForeground": "#d0d7e4", + "MenuItem.background": "#1a212f", + "MenuItem.disabledForeground": "#d0d7e466", + "MenuItem.foreground": "#d0d7e4", + "MenuItem.selectionBackground": "#8196b533", + "MenuItem.selectionForeground": "#d0d7e4", + "NavBar.background": "#181f2c", + "NavBar.borderColor": "#11161f", + "Notification.background": "#1a212f", + "Notification.borderColor": "#11161f", + "Notification.errorBackground": "#e3553526", + "Notification.errorBorderColor": "#E35535", + "Notification.errorForeground": "#d0d7e4", + "Notification.foreground": "#d0d7e4", + "Notification.linkForeground": "#8196b5", + "Notification.MoreButton.background": "#181f2c", + "Notification.MoreButton.foreground": "#d0d7e4", + "Notification.ToolWindow.errorBackground": "#e3553526", + "Notification.ToolWindow.errorBorderColor": "#E35535", + "Notification.ToolWindow.informativeBackground": "#69c3ff26", + "Notification.ToolWindow.informativeBorderColor": "#69C3FF", + "Notification.ToolWindow.warningBackground": "#ff955c26", + "Notification.ToolWindow.warningBorderColor": "#FF955C", + "Panel.background": "#1c2433", + "Panel.foreground": "#d0d7e4", + "ParameterInfo.background": "#1a212f", + "ParameterInfo.borderColor": "#11161f", + "ParameterInfo.currentOverloadBackground": "#8196b51a", + "ParameterInfo.currentParameterForeground": "#8196b5", + "ParameterInfo.disabledForeground": "#d0d7e466", + "ParameterInfo.foreground": "#d0d7e4", + "Plugins.Button.installBackground": "#3cec8526", + "Plugins.Button.installBorderColor": "#3CEC85", + "Plugins.Button.installFillBackground": "#3CEC85", + "Plugins.Button.installFillForeground": "#FFFFFF", + "Plugins.Button.installFocusedBackground": "#3cec8540", + "Plugins.Button.installForeground": "#3CEC85", + "Plugins.Button.updateBackground": "#8196b526", + "Plugins.Button.updateBorderColor": "#8196b5", + "Plugins.Button.updateForeground": "#8196b5", + "Plugins.disabledForeground": "#d0d7e466", + "Plugins.eapTagBackground": "#ff955c33", + "Plugins.eapTagForeground": "#FF955C", + "Plugins.hoverBackground": "#253043", + "Plugins.lightSelectionBackground": "#8196b51a", + "Plugins.paidTagBackground": "#3cec8533", + "Plugins.paidTagForeground": "#3CEC85", + "Plugins.SearchField.background": "#212b3d", + "Plugins.SearchField.borderColor": "#11161f", + "Plugins.SectionHeader.background": "#181f2c", + "Plugins.SectionHeader.foreground": "#d0d7e4", + "Plugins.Tab.hoverBackground": "#253043", + "Plugins.Tab.selectedBackground": "#8196b533", + "Plugins.Tab.selectedForeground": "#d0d7e4", + "Plugins.tagBackground": "#8196b526", + "Plugins.tagForeground": "#8196b5", + "Plugins.trialTagBackground": "#b78aff33", + "Plugins.trialTagForeground": "#B78AFF", + "Popup.Advertiser.background": "#181f2c", + "Popup.Advertiser.borderColor": "#11161f", + "Popup.Advertiser.borderInsets": "1,1,1,1", + "Popup.Advertiser.foreground": "#4a5e84", + "Popup.background": "#1a212f", + "Popup.borderColor": "#11161f", + "Popup.Header.activeBackground": "#181f2c", + "Popup.Header.inactiveBackground": "#181f2c", + "Popup.inactiveBorderColor": "#11161f80", + "Popup.Separator.foreground": "#11161f", + "Popup.Toolbar.background": "#181f2c", + "Popup.Toolbar.borderColor": "#11161f", + "PopupMenu.background": "#1a212f", + "PopupMenu.foreground": "#d0d7e4", + "PopupMenu.selectionBackground": "#8196b533", + "PopupMenu.selectionForeground": "#d0d7e4", + "PopupMenu.translucentBackground": "#1a212ff2", + "ProgressBar.backgroundColor": "#181f2c", + "ProgressBar.failedColor": "#E35535", + "ProgressBar.failedEndColor": "#e97b62", + "ProgressBar.foreground": "#8196b5", + "ProgressBar.indeterminateEndColor": "#b1bed1", + "ProgressBar.indeterminateStartColor": "#8196b5", + "ProgressBar.passedColor": "#3CEC85", + "ProgressBar.passedEndColor": "#6af1a2", + "ProgressBar.progressColor": "#8196b5", + "ProgressBar.selectionBackground": "#181f2c", + "ProgressBar.selectionForeground": "#d0d7e4", + "ProgressBar.trackColor": "#181f2c", + "RunWidget.background": "#181f2c", + "RunWidget.foreground": "#d0d7e4", + "RunWidget.hoverBackground": "#253043", + "RunWidget.iconColor": "#3CEC85", + "RunWidget.runningBackground": "#3cec8526", + "RunWidget.runningForeground": "#d0d7e4", + "RunWidget.runningHoverBackground": "#3cec8540", + "RunWidget.runningIconColor": "#3CEC85", + "RunWidget.stopBackground": "#e3553526", + "RunWidget.stopForeground": "#d0d7e4", + "RunWidget.stopHoverBackground": "#e3553540", + "ScrollBar.background": "#1C243300", + "ScrollBar.hoverThumbColor": "#d0d7e44d", + "ScrollBar.hoverTrackColor": "#1C243300", + "ScrollBar.Mac.hoverThumbBorderColor": "#1C243300", + "ScrollBar.Mac.hoverThumbColor": "#d0d7e44d", + "ScrollBar.Mac.hoverTrackColor": "#1C243300", + "ScrollBar.Mac.thumbBorderColor": "#1C243300", + "ScrollBar.Mac.thumbColor": "#d0d7e426", + "ScrollBar.Mac.trackColor": "#1C243300", + "ScrollBar.Mac.Transparent.hoverThumbBorderColor": "#1C243300", + "ScrollBar.Mac.Transparent.hoverThumbColor": "#d0d7e44d", + "ScrollBar.Mac.Transparent.hoverTrackColor": "#1C243300", + "ScrollBar.Mac.Transparent.thumbBorderColor": "#1C243300", + "ScrollBar.Mac.Transparent.thumbColor": "#d0d7e426", + "ScrollBar.Mac.Transparent.trackColor": "#1C243300", + "ScrollBar.thumbColor": "#d0d7e426", + "ScrollBar.track": "#1C243300", + "ScrollBar.trackColor": "#1C243300", + "ScrollBar.Transparent.hoverThumbColor": "#d0d7e44d", + "ScrollBar.Transparent.hoverTrackColor": "#1C243300", + "ScrollBar.Transparent.thumbColor": "#d0d7e426", + "ScrollBar.Transparent.trackColor": "#1C243300", + "SearchEverywhere.Advertiser.background": "#181f2c", + "SearchEverywhere.Advertiser.foreground": "#4a5e84", + "SearchEverywhere.background": "#1a212f", + "SearchEverywhere.Header.background": "#181f2c", + "SearchEverywhere.List.separatorColor": "#11161f", + "SearchEverywhere.List.separatorForeground": "#4a5e84", + "SearchEverywhere.SearchField.background": "#212b3d", + "SearchEverywhere.SearchField.borderColor": "#11161f", + "SearchEverywhere.Tab.selectedBackground": "#8196b533", + "SearchEverywhere.Tab.selectedForeground": "#d0d7e4", + "SearchField.background": "#212b3d", + "SearchField.errorBackground": "#e3553526", + "SearchField.errorForeground": "#E35535", + "SearchMatch.endBackground": "#eacd614d", + "SearchMatch.endForeground": "#d0d7e4", + "SearchMatch.startBackground": "#eacd614d", + "SearchMatch.startForeground": "#d0d7e4", + "SearchOption.background": "#181f2c", + "SearchOption.selectedBackground": "#8196b533", + "SegmentedButton.focusedSelectedButtonColor": "#8196b5", + "SegmentedButton.selectedButtonColor": "#8196b533", + "SegmentedButton.selectedEndBorderColor": "#8196b5", + "SegmentedButton.selectedStartBorderColor": "#8196b5", + "Separator.foreground": "#11161f", + "Separator.separatorColor": "#11161f", + "Settings.Spotlight.borderColor": "#8196b5", + "SidePanel.background": "#181f2c", + "Slider.background": "#1c2433", + "Slider.buttonBorderColor": "#11161f", + "Slider.buttonColor": "#181f2c", + "Slider.tickColor": "#4a5e84", + "Slider.trackColor": "#181f2c", + "SpeedSearch.background": "#1a212f", + "SpeedSearch.borderColor": "#8196b5", + "SpeedSearch.errorBackground": "#e3553526", + "SpeedSearch.errorBorderColor": "#E35535", + "SpeedSearch.foreground": "#d0d7e4", + "Spinner.background": "#212b3d", + "StatusBar.background": "#181f2c", + "StatusBar.borderColor": "#11161F00", + "StatusBar.hoverBackground": "#253043", + "StatusBar.Widget.hoverBackground": "#253043", + "TabbedPane.background": "#181f2c", + "TabbedPane.borderColor": "#11161f", + "TabbedPane.contentAreaColor": "#1c2433", + "TabbedPane.disabled": "#d0d7e466", + "TabbedPane.focus": "#8196b5", + "TabbedPane.focusColor": "#8196b580", + "TabbedPane.foreground": "#d0d7e4", + "TabbedPane.hoverColor": "#253043", + "TabbedPane.tabSelectionHeight": 3, + "TabbedPane.underlineColor": "#8196b5", + "Table.alternateRowBackground": "#181f2c80", + "Table.background": "#1c2433", + "Table.dropLineColor": "#8196b5", + "Table.focusCellBackground": "#8196b533", + "Table.foreground": "#d0d7e4", + "Table.gridColor": "#11161f", + "Table.hoverBackground": "#253043", + "Table.lightSelectionBackground": "#8196b51a", + "Table.lightSelectionForeground": "#d0d7e4", + "Table.lightSelectionInactiveBackground": "#8196b50d", + "Table.lightSelectionInactiveForeground": "#d0d7e4", + "Table.selectionBackground": "#8196b533", + "Table.selectionForeground": "#d0d7e4", + "Table.selectionInactiveBackground": "#8196b51a", + "Table.selectionInactiveForeground": "#d0d7e4", + "Table.stripeColor": "#181f2c80", + "Tag.background": "#8196b526", + "Tag.foreground": "#8196b5", + "TextArea.background": "#212b3d", + "TextArea.caretForeground": "#8196b5", + "TextArea.foreground": "#d0d7e4", + "TextArea.inactiveBackground": "#212b3d80", + "TextArea.inactiveForeground": "#4a5e84", + "TextArea.selectionBackground": "#8196b533", + "TextArea.selectionForeground": "#d0d7e4", + "TextField.background": "#212b3d", + "TextField.borderColor": "#11161f", + "TextField.caretForeground": "#8196b5", + "TextField.disabledBackground": "#212b3d80", + "TextField.focusedBorderColor": "#8196b5", + "TextField.foreground": "#d0d7e4", + "TextField.highlight": "#8196b533", + "TextField.hoverBorderColor": "#232d40", + "TextField.inactiveBackground": "#212b3d80", + "TextField.inactiveForeground": "#4a5e84", + "TextField.placeholderForeground": "#4a5e84", + "TextField.selectionBackground": "#8196b533", + "TextField.selectionForeground": "#d0d7e4", + "TitlePane.background": "#181f2c", + "TitlePane.Button.hoverBackground": "#253043", + "TitlePane.foreground": "#d0d7e4", + "TitlePane.fullScreen.background": "#181f2c", + "TitlePane.inactiveBackground": "#181f2c", + "TitlePane.inactiveForeground": "#4a5e84", + "TitlePane.infoForeground": "#4a5e84", + "ToggleButton.background": "#181f2c", + "ToggleButton.borderColor": "#11161f", + "ToggleButton.buttonColor": "#d0d7e4", + "ToggleButton.disabledBorderColor": "#11161f80", + "ToggleButton.offBackground": "#181f2c", + "ToggleButton.offForeground": "#4a5e84", + "ToggleButton.onBackground": "#8196b5", + "ToggleButton.onForeground": "#000000", + "ToolBar.background": "#181f2c", + "ToolBar.borderHandleColor": "#11161f", + "ToolBar.floatingBackground": "#1a212f", + "ToolBar.foreground": "#d0d7e4", + "ToolBar.separatorColor": "#11161f", + "ToolTip.Actions.background": "#181f2c", + "ToolTip.Actions.foreground": "#d0d7e4", + "ToolTip.Actions.Info.foreground": "#4a5e84", + "ToolTip.background": "#1a212f", + "ToolTip.borderColor": "#11161f", + "ToolTip.foreground": "#d0d7e4", + "ToolTip.infoForeground": "#4a5e84", + "ToolTip.separatorColor": "#11161f", + "ToolTip.shortcutForeground": "#4a5e84", + "ToolWindow.background": "#1c2433", + "ToolWindow.Button.hoverBackground": "#253043", + "ToolWindow.Button.selectedBackground": "#8196b533", + "ToolWindow.Button.selectedForeground": "#d0d7e4", + "ToolWindow.Header.background": "#181f2c", + "ToolWindow.Header.borderColor": "#11161f", + "ToolWindow.Header.closeButton.background": "#1C243300", + "ToolWindow.Header.inactiveBackground": "#181f2c", + "ToolWindow.HeaderCloseButton.background": "#1C243300", + "ToolWindow.HeaderTab.hoverBackground": "#253043", + "ToolWindow.HeaderTab.hoverInactiveBackground": "#253043", + "ToolWindow.HeaderTab.selectedBackground": "#1c2433", + "ToolWindow.HeaderTab.selectedInactiveBackground": "#1a212f", + "ToolWindow.HeaderTab.underlineColor": "#8196b5", + "ToolWindow.HeaderTab.underlinedTabBackground": "#1c2433", + "ToolWindow.HeaderTab.underlinedTabForeground": "#d0d7e4", + "ToolWindow.HeaderTab.underlinedTabInactiveBackground": "#1a212f", + "ToolWindow.HeaderTab.underlinedTabInactiveForeground": "#4a5e84", + "ToolWindow.HeaderTab.underlineHeight": 3, + "ToolWindow.Stripe.background": "#181f2c", + "ToolWindow.Stripe.borderColor": "#11161F00", + "Tree.background": "#1c2433", + "Tree.errorForeground": "#E35535", + "Tree.foreground": "#d0d7e4", + "Tree.hoverBackground": "#253043", + "Tree.modifiedItemForeground": "#69C3FF", + "Tree.rowHeight": 24, + "Tree.selectionBackground": "#8196b533", + "Tree.selectionForeground": "#d0d7e4", + "Tree.selectionInactiveBackground": "#8196b51a", + "ValidationTooltip.errorBackground": "#e3553526", + "ValidationTooltip.errorBorderColor": "#E35535", + "ValidationTooltip.warningBackground": "#ff955c26", + "ValidationTooltip.warningBorderColor": "#FF955C", + "VersionControl.FileHistory.Commit.otherBranchBackground": "#b78aff1a", + "VersionControl.FileHistory.Commit.selectedBranchBackground": "#8196b51a", + "VersionControl.GitCommits.graphColor": "#8196b5", + "VersionControl.GitLog.headIconColor": "#EACD61", + "VersionControl.GitLog.localBranchIconColor": "#3CEC85", + "VersionControl.GitLog.otherIconColor": "#B78AFF", + "VersionControl.GitLog.remoteBranchIconColor": "#22ECDB", + "VersionControl.GitLog.tagIconColor": "#EACD61", + "VersionControl.HgLog.bookmarkIconColor": "#3CEC85", + "VersionControl.HgLog.branchIconColor": "#22ECDB", + "VersionControl.HgLog.closedBranchIconColor": "#22ecdb80", + "VersionControl.HgLog.headIconColor": "#EACD61", + "VersionControl.HgLog.localTagIconColor": "#FF955C", + "VersionControl.HgLog.mqTagIconColor": "#B78AFF", + "VersionControl.HgLog.tagIconColor": "#EACD61", + "VersionControl.HgLog.tipIconColor": "#F38CEC", + "VersionControl.Log.Commit.currentBranchBackground": "#8196b51a", + "VersionControl.Log.Commit.hoveredBackground": "#253043", + "VersionControl.Log.Commit.unmatchedForeground": "#4a5e84", + "VersionControl.Ref.background": "#8196b526", + "VersionControl.Ref.backgroundBase": "#181f2c", + "VersionControl.RefLabel.background": "#8196b526", + "VersionControl.RefLabel.backgroundBase": "#181f2c", + "VersionControl.RefLabel.foreground": "#d0d7e4", + "WelcomeScreen.background": "#1c2433", + "WelcomeScreen.borderColor": "#11161f", + "WelcomeScreen.captionBackground": "#181f2c", + "WelcomeScreen.captionForeground": "#d0d7e4", + "WelcomeScreen.Details.background": "#181f2c", + "WelcomeScreen.footerBackground": "#181f2c", + "WelcomeScreen.footerForeground": "#4a5e84", + "WelcomeScreen.groupIconBorderColor": "#11161f", + "WelcomeScreen.headerBackground": "#181f2c", + "WelcomeScreen.headerForeground": "#d0d7e4", + "WelcomeScreen.Projects.actions.background": "#181f2c", + "WelcomeScreen.Projects.actions.selectionBackground": "#8196b533", + "WelcomeScreen.Projects.background": "#1c2433", + "WelcomeScreen.Projects.selectionBackground": "#8196b533", + "WelcomeScreen.Projects.selectionInactiveBackground": "#8196b51a", + "WelcomeScreen.separatorColor": "#11161f", + "WelcomeScreen.SidePanel.background": "#181f2c", + "window.border": "#11161f" + } +} \ No newline at end of file diff --git a/bearded-theme-arc.xml b/bearded-theme-arc.xml new file mode 100644 index 0000000..50246b6 --- /dev/null +++ b/bearded-theme-arc.xml @@ -0,0 +1,1046 @@ + + + + Bearded Theme Generator + JetBrains IDE + 2024.1 + Bearded Theme Arc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bearded-theme-black-&-ruby.xml b/bearded-theme-black-&-ruby.xml new file mode 100644 index 0000000..a54b2c9 --- /dev/null +++ b/bearded-theme-black-&-ruby.xml @@ -0,0 +1,1045 @@ + + + + Bearded Theme Generator + JetBrains IDE + 2024.1 + Bearded Theme Black & Ruby + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index c9404ad..8ff90cf 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,25 @@ }, "type": "module", "scripts": { - "build": "vite-node src/build.ts all", - "build:vscode": "vite-node src/generators/vscode/index.ts", - "build:zed": "vite-node src/generators/zed/index.ts", + "clean": "node -e \"const fs=require('fs');['dist/vscode','dist/zed','dist/jetbrains'].forEach(d=>{if(fs.existsSync(d))fs.rmSync(d,{recursive:true})});console.log('Cleaned dist folders')\"", + "clean:vscode": "node -e \"const fs=require('fs');if(fs.existsSync('dist/vscode'))fs.rmSync('dist/vscode',{recursive:true});console.log('Cleaned dist/vscode')\"", + "clean:zed": "node -e \"const fs=require('fs');if(fs.existsSync('dist/zed'))fs.rmSync('dist/zed',{recursive:true});console.log('Cleaned dist/zed')\"", + "clean:jetbrains": "node -e \"const fs=require('fs');if(fs.existsSync('dist/jetbrains'))fs.rmSync('dist/jetbrains',{recursive:true});console.log('Cleaned dist/jetbrains')\"", + "build": "npm run clean && vite-node src/build.ts all", + "build:vscode": "npm run clean:vscode && vite-node src/generators/vscode/index.ts", + "build:zed": "npm run clean:zed && vite-node src/generators/zed/index.ts", + "build:jetbrains": "npm run clean:jetbrains && vite-node src/generators/jetbrains/index.ts", "build:ext:vscode": "npm run build:vscode && vsce package --out ./releases/%npm_package_version%.vsix", "build:ext:zed": "npm run build:zed", + "build:ext:jetbrains": "npm run build:jetbrains && node -e \"const{execSync}=require('child_process');const{existsSync}=require('fs');const{join}=require('path');const dir=join(process.cwd(),'dist','jetbrains');const jar=join(dir,'gradle','wrapper','gradle-wrapper.jar');if(!existsSync(jar)){console.log('Downloading gradle-wrapper.jar...');execSync('powershell -Command \\\"Invoke-WebRequest -Uri https://github.com/gradle/gradle/raw/v8.13.0/gradle/wrapper/gradle-wrapper.jar -OutFile gradle/wrapper/gradle-wrapper.jar\\\"',{cwd:dir,stdio:'inherit'})}const isWin=process.platform==='win32';const cmd=isWin?'gradlew.bat':'./gradlew';execSync(cmd+' buildPlugin',{cwd:dir,stdio:'inherit'})\"", + "install:jetbrains:local": "npm run build:jetbrains && node -e \"const fs=require('fs'),os=require('os'),path=require('path');const home=os.homedir();const configDirs=['WebStorm','IntelliJIdea','PyCharm','PhpStorm','GoLand','Rider','RubyMine','CLion','DataGrip'];const years=['2024.1','2024.2','2024.3','2025.1'];let installed=false;for(const ide of configDirs){for(const year of years){const configPath=path.join(home,'.config','JetBrains',ide+year,'options');if(fs.existsSync(path.dirname(configPath))){console.log('Found:',ide+year);installed=true}}}if(!installed)console.log('No JetBrains IDE config found. Install themes manually.')\"", + "dev:jetbrains:install": "npm run build:jetbrains && npm run install:jetbrains:local", "publish:zed": "echo 'To publish Zed extension: 1) Push changes to GitHub 2) Open PR to zed-industries/extensions repo'", "zed:dev": "echo 'Install as dev extension: Open Zed > Extensions > Install Dev Extension > Select dist/zed folder'", "build:env": "tsc load-env.ts --esModuleInterop", "dev:vscode": "nodemon --exec \"vite-node src/generators/vscode/index.ts\"", "dev:zed": "nodemon --exec \"vite-node src/generators/zed/index.ts\"", + "dev:jetbrains": "nodemon --exec \"vite-node src/generators/jetbrains/index.ts\"", "lint": "eslint src/**/*.{js,ts}", "fix": "eslint src/**/*.{js,ts} --fix", "release": "gh release create v%npm_package_version% --notes-file ./releases/%npm_package_version%.md --generate-notes", diff --git a/src/build.ts b/src/build.ts index ea9e7e1..1c5dd93 100644 --- a/src/build.ts +++ b/src/build.ts @@ -1,13 +1,75 @@ /** * Bearded Theme Build Orchestrator * - * This script orchestrates the build process for both VSCode and Zed themes. - * Run with: vite-node src/build.ts [vscode|zed|all] + * This script orchestrates the build process for VSCode, Zed, and JetBrains themes. + * Run with: vite-node src/build.ts [vscode|zed|jetbrains|all] */ import { execSync } from "child_process"; +import { existsSync } from "fs"; +import { join } from "path"; -type BuildTarget = "all" | "vscode" | "zed"; +type BuildTarget = "all" | "jetbrains" | "vscode" | "zed"; + +function buildJetBrains(): void { + console.log("\n🟣 Building JetBrains themes...\n"); + execSync("vite-node src/generators/jetbrains/index.ts", { stdio: "inherit" }); +} + +function buildJetBrainsPlugin(): void { + console.log("\n📦 Building JetBrains plugin package...\n"); + + const jetbrainsDir = join(process.cwd(), "dist", "jetbrains"); + + // Check if Java is available + if (!isCommandAvailable("java")) { + console.warn("\n⚠️ Java not found in PATH."); + console.warn(" Make sure Java 11+ is installed and JAVA_HOME is set."); + console.warn(" Theme files were still generated in dist/jetbrains/\n"); + console.warn(" To build manually after installing Java:"); + console.warn(" cd dist/jetbrains"); + console.warn(" gradlew.bat buildPlugin (Windows)"); + console.warn(" ./gradlew buildPlugin (macOS/Linux)\n"); + return; + } + + try { + execSync("java -version", { stdio: "pipe" }); + } catch { + console.warn("\n⚠️ Could not verify Java installation."); + console.warn(" Theme files were still generated in dist/jetbrains/\n"); + return; + } + + // Determine the correct Gradle wrapper command for the platform + const isWindows = process.platform === "win32"; + const gradleWrapper = isWindows ? "gradlew.bat" : "./gradlew"; + + // Initialize the wrapper if needed + if (!initGradleWrapper(jetbrainsDir)) { + console.warn("\n⚠️ Could not initialize Gradle wrapper."); + console.warn(" Please install Gradle and run: gradle wrapper --gradle-version 8.5"); + console.warn(" Or download gradle-wrapper.jar manually to dist/jetbrains/gradle/wrapper/"); + console.warn(" Theme files were still generated in dist/jetbrains/\n"); + return; + } + + // Build the plugin using the wrapper with cwd option + console.log("\n 🔨 Running Gradle build...\n"); + try { + execSync(`${gradleWrapper} buildPlugin`, { + cwd: jetbrainsDir, + stdio: "inherit", + }); + + console.log("\n✅ JetBrains plugin built successfully!"); + console.log(" Plugin ZIP: dist/jetbrains/build/distributions/\n"); + } catch { + console.warn("\n⚠️ Gradle build failed."); + console.warn(" Check the error messages above for details."); + console.warn(" Theme files were still generated in dist/jetbrains/\n"); + } +} function buildVscode(): void { console.log("\n🔵 Building VSCode themes...\n"); @@ -21,12 +83,86 @@ function buildZed(): void { function getBuildTarget(): BuildTarget { const arg = process.argv[2]?.toLowerCase(); - if (arg === "vscode" || arg === "zed" || arg === "all") { + if ( + arg === "vscode" || + arg === "zed" || + arg === "jetbrains" || + arg === "all" + ) { return arg; } return "all"; } +/** + * Initialize or update the Gradle wrapper + */ +function initGradleWrapper(jetbrainsDir: string): boolean { + const isWindows = process.platform === "win32"; + const wrapperJar = join(jetbrainsDir, "gradle", "wrapper", "gradle-wrapper.jar"); + + // If wrapper jar already exists, we're good + if (existsSync(wrapperJar)) { + return true; + } + + console.log(" 📥 Gradle wrapper jar not found, initializing..."); + + // Try using gradle command to generate the wrapper + if (isCommandAvailable("gradle")) { + console.log(" Using 'gradle' to generate wrapper..."); + try { + execSync("gradle wrapper --gradle-version 8.5", { + cwd: jetbrainsDir, + stdio: "inherit", + }); + return true; + } catch (error) { + console.warn(" Failed to generate wrapper with gradle:", error); + } + } + + // Try downloading the wrapper jar directly + console.log(" Attempting to download gradle-wrapper.jar..."); + const wrapperJarUrl = + "https://github.com/gradle/gradle/raw/v8.13.0/gradle/wrapper/gradle-wrapper.jar"; + + try { + if (isWindows) { + // Use PowerShell to download on Windows + execSync( + `powershell -Command "New-Item -ItemType Directory -Force -Path 'gradle\\wrapper' | Out-Null; Invoke-WebRequest -Uri '${wrapperJarUrl}' -OutFile 'gradle\\wrapper\\gradle-wrapper.jar'"`, + { cwd: jetbrainsDir, stdio: "inherit" }, + ); + } else { + // Use curl on Unix + execSync( + `mkdir -p gradle/wrapper && curl -L -o gradle/wrapper/gradle-wrapper.jar "${wrapperJarUrl}"`, + { cwd: jetbrainsDir, stdio: "inherit" }, + ); + } + return true; + } catch (error) { + console.warn(" Failed to download wrapper jar:", error); + } + + return false; +} + +/** + * Check if a command is available in the system PATH + */ +function isCommandAvailable(command: string): boolean { + try { + const isWindows = process.platform === "win32"; + const checkCmd = isWindows ? `where ${command}` : `which ${command}`; + execSync(checkCmd, { stdio: "pipe" }); + return true; + } catch { + return false; + } +} + async function main(): Promise { const target = getBuildTarget(); @@ -42,6 +178,11 @@ async function main(): Promise { case "all": buildVscode(); buildZed(); + buildJetBrains(); + buildJetBrainsPlugin(); + break; + case "jetbrains": + buildJetBrains(); break; case "vscode": buildVscode(); @@ -60,6 +201,10 @@ async function main(): Promise { if (target === "zed" || target === "all") { console.log(" - dist/zed/themes/"); } + if (target === "jetbrains" || target === "all") { + console.log(" - dist/jetbrains/themes/"); + console.log(" - dist/jetbrains/resources/META-INF/"); + } } catch (error) { console.error("\n❌ Build failed:", error); process.exit(1); diff --git a/src/generators/jetbrains/README.md b/src/generators/jetbrains/README.md new file mode 100644 index 0000000..5f4c083 --- /dev/null +++ b/src/generators/jetbrains/README.md @@ -0,0 +1,190 @@ +# JetBrains Theme Generator + +This directory contains the theme generator for JetBrains IDEs (WebStorm, IntelliJ IDEA, PyCharm, PhpStorm, Rider, GoLand, etc.). + +## Structure + +``` +jetbrains/ +├── index.ts # Main build script +├── types.ts # TypeScript type definitions for JetBrains themes +├── ui.ts # UI color mappings +├── theme.ts # Theme JSON builder +├── editor-scheme.ts # Editor color scheme XML generator +├── plugin.ts # Plugin manifest (plugin.xml) generator +├── utils.ts # Color utility functions +└── README.md # This file +``` + +## Generated Output + +The build process generates a complete Gradle-based plugin structure: + +``` +dist/jetbrains/ +├── resources/ +│ └── META-INF/ +│ └── plugin.xml # Plugin manifest +├── themes/ +│ ├── bearded-theme-*.theme.json # UI theme files +│ └── bearded-theme-*.xml # Editor color schemes +├── build.gradle.kts # Gradle build configuration +├── settings.gradle.kts # Gradle settings +├── gradle.properties # Gradle properties +└── README.md # Installation instructions +``` + +## Building Themes + +### Generate Theme Files Only + +```bash +npm run build:jetbrains +``` + +This generates all theme files in `dist/jetbrains/` but does not build the plugin package. + +### Build Plugin Package (ZIP) + +```bash +npm run build:ext:jetbrains +``` + +This generates the theme files AND builds the plugin ZIP file. Requires: +- Java 11 or higher installed +- Internet connection (for Gradle to download dependencies) + +The plugin ZIP will be created in `dist/jetbrains/build/distributions/`. + +### Full Build (All Platforms) + +```bash +npm run build +``` + +This builds VS Code, Zed, and JetBrains themes, plus the JetBrains plugin package. + +## Installation + +### Method 1: Install from Disk (Development) + +1. Build the plugin: `npm run build:ext:jetbrains` +2. Open your JetBrains IDE +3. Go to **Settings/Preferences** → **Plugins** +4. Click the gear icon ⚙️ → **Install Plugin from Disk...** +5. Select the ZIP file from `dist/jetbrains/build/distributions/` +6. Restart the IDE + +### Method 2: Quick Install (Local Themes Only) + +```bash +npm run install:jetbrains:local +``` + +This copies the theme files directly to your IDE's config directory for quick testing. + +### Method 3: Development Workflow + +```bash +npm run dev:jetbrains:install +``` + +This builds and installs the themes in one command, useful during development. + +## Theme Structure + +### theme.json + +Each theme has a `.theme.json` file that defines: +- Theme metadata (name, author, dark/light) +- Parent theme (Islands Dark/Light for modern UI) +- Named colors for reuse +- UI component colors + +```json +{ + "name": "Bearded Theme Arc", + "dark": true, + "author": "BeardedBear", + "parentTheme": "Islands Dark", + "editorScheme": "/themes/bearded-theme-arc.xml", + "colors": { + "primary": "#8196b5", + "background": "#1c2433" + }, + "ui": { + "*": { + "background": "#1c2433", + "foreground": "#c3cfd9" + }, + "Button.default.startBackground": "#8196b5" + } +} +``` + +### Editor Scheme (XML) + +Each theme also has an `.xml` file for syntax highlighting: +- Color definitions for editor elements +- Syntax highlighting attributes +- Console colors +- Diff/VCS colors + +## Adding New UI Keys + +JetBrains IDEs support hundreds of UI component keys. To add new ones: + +1. Find the key name using the **UI Inspector** in the IDE: + - Help → Diagnostic Tools → UI Inspector + - Click on any UI element to see its properties + +2. Add the key to `types.ts` in the `JetBrainsUiColors` interface + +3. Add the color mapping in `ui.ts` + +## Islands Theme Support + +The generator uses JetBrains' new Islands theme style by default: +- Sets `parentTheme` to "Islands Dark" or "Islands Light" +- Uses rounded corners and modern styling +- Hides sidebar borders for cleaner appearance + +Reference: https://plugins.jetbrains.com/docs/intellij/supporting-islands-theme.html + +## Testing + +1. Build the themes: `npm run build:jetbrains` +2. Install in IDE (see Installation above) +3. Restart the IDE +4. Go to **Settings** → **Appearance & Behavior** → **Appearance** +5. Select a Bearded Theme from the Theme dropdown +6. Verify: + - UI colors are correct + - Syntax highlighting works + - No console errors + +## Troubleshooting + +### "Could not resolve all files for configuration" + +Make sure you have Java 11+ installed and `JAVA_HOME` is set correctly. + +### Theme not appearing in IDE + +- Verify the plugin is installed (Settings → Plugins → Installed) +- Check the IDE's log for errors (Help → Show Log in...) +- Ensure the theme JSON is valid + +### Colors look wrong + +- Check that the hex colors don't have `#` prefix in wrong places +- Verify alpha values are in correct format (RRGGBBAA) +- Some keys may be overridden by other settings + +## Resources + +- [Developing Themes](https://plugins.jetbrains.com/docs/intellij/developing-themes.html) +- [Customizing Themes](https://plugins.jetbrains.com/docs/intellij/themes-customize.html) +- [Theme Extras (Editor Schemes)](https://plugins.jetbrains.com/docs/intellij/themes-extras.html) +- [Islands Theme](https://plugins.jetbrains.com/docs/intellij/supporting-islands-theme.html) +- [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template) diff --git a/src/generators/jetbrains/editor-scheme.ts b/src/generators/jetbrains/editor-scheme.ts new file mode 100644 index 0000000..af319da --- /dev/null +++ b/src/generators/jetbrains/editor-scheme.ts @@ -0,0 +1,594 @@ +/** + * JetBrains Editor Color Scheme Generator + * + * Generates .xml editor color scheme files for JetBrains IDEs. + * These files define syntax highlighting colors for the editor. + * + * References: + * - https://plugins.jetbrains.com/docs/intellij/themes-extras.html + * - Editor color scheme XML format from IntelliJ Platform + */ + +import { colord as c } from "colord"; + +import { ThemeRegistryEntry } from "../../shared/theme-registry"; +import { Theme } from "../../shared/types"; +import { toHex } from "./utils"; + +/** + * Build an editor color scheme XML string + * + * @param entry - Theme registry entry + * @returns XML string for the editor color scheme + */ +export function buildEditorScheme(entry: ThemeRegistryEntry): string { + const { name, options, theme } = entry; + const isDark = !options.light; + const schemeName = escapeXmlAttribute(`Bearded Theme ${name}`); + const parentScheme = isDark ? "Darcula" : "Default"; + + const xml = ` + + + Bearded Theme Generator + JetBrains IDE + 2024.1 + ${schemeName} + + +${buildColorOptions(theme, options.light, options.hc)} + + +${buildAttributeOptions(theme, options.light, options.hc)} + +`; + + return xml; +} + +/** + * Build attribute options for syntax highlighting + * + * @param theme - Theme object + * @param isLight - Whether this is a light theme + * @param isHc - Whether this is a high contrast theme + * @returns XML string of attribute options + */ +function buildAttributeOptions( + theme: Theme, + isLight?: boolean, + isHc?: boolean, +): string { + const { colors, ui } = theme; + + // Helper to create an attribute option + const attr = ( + name: string, + opts: { + background?: string; + effectColor?: string; + effectType?: number; + fontType?: number; + foreground?: string; + }, + ): string => { + const parts: string[] = []; + + if (opts.foreground) { + parts.push(``; + }; + + // Font types: 0=plain, 1=bold, 2=italic, 3=bold+italic + // Effect types: 0=bordered, 1=line underscore, 2=wave underscore, + // 3=strikeout, 4=bold line underscore, 5=dotted line + + const attributes: string[] = [ + // Default text - background is critical for editor background color + attr("TEXT", { background: ui.uibackground, foreground: ui.default }), + + // Comments + attr("DEFAULT_BLOCK_COMMENT", { fontType: 2, foreground: ui.defaultalt }), + attr("DEFAULT_DOC_COMMENT", { fontType: 2, foreground: ui.defaultalt }), + attr("DEFAULT_DOC_COMMENT_TAG", { + fontType: 3, + foreground: ui.defaultalt, + }), + attr("DEFAULT_DOC_COMMENT_TAG_VALUE", { + fontType: 2, + foreground: colors.salmon, + }), + attr("DEFAULT_DOC_MARKUP", { foreground: ui.defaultalt }), + attr("DEFAULT_LINE_COMMENT", { fontType: 2, foreground: ui.defaultalt }), + + // Keywords + attr("DEFAULT_KEYWORD", { foreground: colors.yellow }), + + // Identifiers + attr("DEFAULT_IDENTIFIER", { foreground: ui.default }), + + // Strings + attr("DEFAULT_STRING", { foreground: colors.green }), + attr("DEFAULT_VALID_STRING_ESCAPE", { foreground: colors.orange }), + attr("DEFAULT_INVALID_STRING_ESCAPE", { + effectColor: colors.red, + effectType: 2, + foreground: colors.red, + }), + + // Numbers + attr("DEFAULT_NUMBER", { foreground: colors.red }), + + // Operators and punctuation + attr("DEFAULT_OPERATION_SIGN", { foreground: colors.yellow }), + attr("DEFAULT_PARENTHS", { + foreground: isHc ? ui.default : c(ui.default).alpha(0.6).toHex(), + }), + attr("DEFAULT_BRACKETS", { + foreground: isHc ? ui.default : c(ui.default).alpha(0.6).toHex(), + }), + attr("DEFAULT_BRACES", { + foreground: isHc ? ui.default : c(ui.default).alpha(0.6).toHex(), + }), + attr("DEFAULT_COMMA", { + foreground: isHc ? ui.default : c(ui.default).alpha(0.6).toHex(), + }), + attr("DEFAULT_DOT", { + foreground: isHc ? ui.default : c(ui.default).alpha(0.6).toHex(), + }), + attr("DEFAULT_SEMICOLON", { + foreground: isHc ? ui.default : c(ui.default).alpha(0.6).toHex(), + }), + + // Constants + attr("DEFAULT_CONSTANT", { foreground: colors.red }), + + // Classes and Types + attr("DEFAULT_CLASS_NAME", { foreground: colors.greenAlt }), + attr("DEFAULT_CLASS_REFERENCE", { foreground: colors.greenAlt }), + attr("DEFAULT_INTERFACE_NAME", { foreground: colors.greenAlt }), + + // Functions and Methods + attr("DEFAULT_FUNCTION_CALL", { foreground: colors.blue }), + attr("DEFAULT_FUNCTION_DECLARATION", { foreground: colors.blue }), + attr("DEFAULT_INSTANCE_METHOD", { foreground: colors.blue }), + attr("DEFAULT_STATIC_METHOD", { fontType: 2, foreground: colors.blue }), + + // Fields and Properties + attr("DEFAULT_INSTANCE_FIELD", { foreground: ui.default }), + attr("DEFAULT_STATIC_FIELD", { fontType: 2, foreground: ui.default }), + + // Parameters + attr("DEFAULT_PARAMETER", { foreground: colors.pink }), + + // Local variables + attr("DEFAULT_LOCAL_VARIABLE", { foreground: colors.salmon }), + attr("DEFAULT_REASSIGNED_LOCAL_VARIABLE", { + effectColor: colors.salmon, + effectType: 1, + foreground: colors.salmon, + }), + attr("DEFAULT_REASSIGNED_PARAMETER", { + effectColor: colors.pink, + effectType: 1, + foreground: colors.pink, + }), + + // Metadata / Annotations / Decorators + attr("DEFAULT_METADATA", { foreground: colors.pink }), + + // Labels + attr("DEFAULT_LABEL", { foreground: colors.yellow }), + + // Predefined symbols + attr("DEFAULT_PREDEFINED_SYMBOL", { foreground: colors.turquoize }), + + // Template language + attr("DEFAULT_TEMPLATE_LANGUAGE_COLOR", { + background: c(ui.uibackground).lighten(0.02).toHex(), + }), + + // Markup languages + attr("DEFAULT_TAG", { foreground: colors.blue }), + attr("DEFAULT_ATTRIBUTE", { foreground: colors.yellow }), + attr("DEFAULT_ENTITY", { foreground: colors.orange }), + + // HTML specific + attr("HTML_TAG_NAME", { foreground: colors.blue }), + attr("HTML_ATTRIBUTE_NAME", { foreground: colors.yellow }), + attr("HTML_ATTRIBUTE_VALUE", { foreground: colors.green }), + attr("HTML_ENTITY_REFERENCE", { foreground: colors.orange }), + + // XML specific + attr("XML_TAG_NAME", { foreground: colors.blue }), + attr("XML_ATTRIBUTE_NAME", { foreground: colors.yellow }), + attr("XML_ATTRIBUTE_VALUE", { foreground: colors.green }), + attr("XML_ENTITY_REFERENCE", { foreground: colors.orange }), + attr("XML_TAG", { foreground: colors.blue }), + attr("XML_TAG_DATA", { foreground: ui.default }), + attr("XML_PROLOGUE", { foreground: ui.defaultalt }), + attr("XML_NS_PREFIX", { foreground: colors.turquoize }), + + // CSS specific + attr("CSS.COLOR", { foreground: colors.orange }), + attr("CSS.FUNCTION", { foreground: colors.blue }), + attr("CSS.IDENT", { foreground: ui.default }), + attr("CSS.IMPORTANT", { fontType: 1, foreground: colors.red }), + attr("CSS.KEYWORD", { foreground: colors.yellow }), + attr("CSS.NUMBER", { foreground: colors.red }), + attr("CSS.PROPERTY_NAME", { foreground: colors.turquoize }), + attr("CSS.PROPERTY_VALUE", { foreground: ui.default }), + attr("CSS.PSEUDO", { foreground: colors.pink }), + attr("CSS.STRING", { foreground: colors.green }), + attr("CSS.TAG_NAME", { foreground: colors.blue }), + attr("CSS.URL", { foreground: colors.green }), + + // SCSS/SASS specific + attr("SCSS_VARIABLE", { foreground: colors.salmon }), + attr("SASS_MIXIN", { foreground: colors.purple }), + + // JavaScript/TypeScript specific + attr("JS.GLOBAL_FUNCTION", { foreground: colors.blue }), + attr("JS.GLOBAL_VARIABLE", { foreground: colors.salmon }), + attr("JS.INSTANCE_MEMBER_FUNCTION", { foreground: colors.blue }), + attr("JS.LOCAL_VARIABLE", { foreground: colors.salmon }), + attr("JS.PARAMETER", { foreground: colors.pink }), + attr("JS.REGEXP", { foreground: colors.orange }), + + attr("TS.MODULE_NAME", { foreground: colors.greenAlt }), + attr("TS.TYPE_PARAMETER", { foreground: colors.purple }), + + // JSON specific + attr("JSON.KEYWORD", { foreground: colors.turquoize }), + attr("JSON.PROPERTY_KEY", { foreground: colors.salmon }), + attr("JSON.STRING", { foreground: colors.green }), + + // YAML specific + attr("YAML_ANCHOR", { foreground: colors.purple }), + attr("YAML_SCALAR_KEY", { foreground: colors.turquoize }), + attr("YAML_SCALAR_VALUE", { foreground: ui.default }), + attr("YAML_SIGN", { + foreground: isHc ? ui.default : c(ui.default).alpha(0.6).toHex(), + }), + + // Markdown specific + attr("MARKDOWN_BOLD", { fontType: 1, foreground: colors.salmon }), + attr("MARKDOWN_CODE_SPAN", { foreground: colors.purple }), + attr("MARKDOWN_HEADER", { fontType: 1, foreground: colors.yellow }), + attr("MARKDOWN_HEADER_LEVEL_1", { fontType: 1, foreground: colors.yellow }), + attr("MARKDOWN_HEADER_LEVEL_2", { fontType: 1, foreground: colors.yellow }), + attr("MARKDOWN_HEADER_LEVEL_3", { fontType: 1, foreground: colors.yellow }), + attr("MARKDOWN_HEADER_LEVEL_4", { fontType: 1, foreground: colors.yellow }), + attr("MARKDOWN_HEADER_LEVEL_5", { fontType: 1, foreground: colors.yellow }), + attr("MARKDOWN_HEADER_LEVEL_6", { fontType: 1, foreground: colors.yellow }), + attr("MARKDOWN_ITALIC", { fontType: 2, foreground: colors.orange }), + attr("MARKDOWN_LINK_DESTINATION", { foreground: colors.blue }), + attr("MARKDOWN_LINK_TEXT", { foreground: colors.green }), + + // Python specific + attr("PY.BUILTIN_NAME", { foreground: colors.turquoize }), + attr("PY.DECORATOR", { foreground: colors.pink }), + attr("PY.FUNC_DEFINITION", { foreground: colors.blue }), + attr("PY.KEYWORD_ARGUMENT", { foreground: colors.pink }), + attr("PY.PREDEFINED_DEFINITION", { foreground: colors.turquoize }), + attr("PY.PREDEFINED_USAGE", { foreground: colors.turquoize }), + attr("PY.SELF_PARAMETER", { fontType: 2, foreground: colors.red }), + attr("PY.STRING.B", { foreground: colors.green }), + attr("PY.STRING.U", { foreground: colors.green }), + + // Rust specific + attr("RUST_ATTRIBUTE", { foreground: colors.pink }), + attr("RUST_LIFETIME", { foreground: colors.purple }), + attr("RUST_MACRO", { foreground: colors.turquoize }), + + // Go specific + attr("GO_BUILTIN_CONSTANT", { foreground: colors.red }), + attr("GO_BUILTIN_FUNCTION_CALL", { foreground: colors.turquoize }), + attr("GO_BUILTIN_TYPE_REFERENCE", { foreground: colors.purple }), + attr("GO_BUILTIN_VARIABLE", { foreground: colors.red }), + attr("GO_EXPORTED_FUNCTION", { foreground: colors.blue }), + attr("GO_PACKAGE", { foreground: colors.greenAlt }), + attr("GO_STRUCT_EXPORTED_MEMBER", { foreground: ui.default }), + attr("GO_TYPE_REFERENCE", { foreground: colors.greenAlt }), + + // Kotlin specific + attr("KOTLIN_LABEL", { foreground: colors.yellow }), + attr("KOTLIN_MUTABLE_VARIABLE", { + effectColor: colors.salmon, + effectType: 1, + foreground: colors.salmon, + }), + attr("KOTLIN_NAMED_ARGUMENT", { foreground: colors.pink }), + attr("KOTLIN_PACKAGE_FUNCTION_CALL", { foreground: colors.blue }), + + // Java specific + attr("ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES", { foreground: colors.pink }), + attr("ANNOTATION_NAME_ATTRIBUTES", { foreground: colors.pink }), + attr("ENUM_CONST", { foreground: colors.red }), + attr("IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES", { + foreground: colors.pink, + }), + attr("STATIC_FINAL_FIELD_ATTRIBUTES", { fontType: 2, foreground: colors.red }), + attr("TYPE_PARAMETER_NAME_ATTRIBUTES", { foreground: colors.purple }), + + // SQL specific + attr("SQL_DATABASE_OBJECT", { foreground: colors.greenAlt }), + attr("SQL_KEYWORD", { foreground: colors.yellow }), + attr("SQL_PROCEDURE", { foreground: colors.blue }), + attr("SQL_STRING", { foreground: colors.green }), + attr("SQL_TABLE", { foreground: colors.greenAlt }), + attr("SQL_COLUMN", { foreground: colors.salmon }), + + // Shell specific + attr("BASH.EXTERNAL_COMMAND", { foreground: colors.blue }), + attr("BASH.FUNCTION_DEF_NAME", { foreground: colors.blue }), + attr("BASH.SHEBANG", { fontType: 2, foreground: ui.defaultalt }), + attr("BASH.VAR_DEF", { foreground: colors.salmon }), + attr("BASH.VAR_USE", { foreground: colors.salmon }), + + // Error and warning markers + attr("BAD_CHARACTER", { effectColor: colors.red, effectType: 2 }), + attr("DEPRECATED_ATTRIBUTES", { effectColor: ui.defaultalt, effectType: 3 }), + attr("ERRORS_ATTRIBUTES", { + effectColor: colors.red, + effectType: 2, + }), + attr("INFO_ATTRIBUTES", { + effectColor: colors.blue, + effectType: 1, + }), + attr("MARKED_FOR_REMOVAL_ATTRIBUTES", { + effectColor: colors.red, + effectType: 3, + }), + attr("NOT_USED_ELEMENT_ATTRIBUTES", { foreground: ui.defaultalt }), + attr("RUNTIME_ERROR", { effectColor: colors.red, effectType: 2 }), + attr("TYPO", { effectColor: colors.green, effectType: 2 }), + attr("WARNING_ATTRIBUTES", { effectColor: colors.orange, effectType: 2 }), + attr("WEAK_WARNING_ATTRIBUTES", { + effectColor: colors.yellow, + effectType: 1, + }), + attr("WRONG_REFERENCES_ATTRIBUTES", { + effectColor: colors.red, + effectType: 2, + foreground: colors.red, + }), + + // Injected language + attr("INJECTED_LANGUAGE_FRAGMENT", { + background: c(ui.uibackground).lighten(0.03).toHex(), + }), + + // Todo / Fixme + attr("TODO_DEFAULT_ATTRIBUTES", { fontType: 2, foreground: colors.yellow }), + + // Diff and merge + attr("DIFF_CONFLICT", { + background: c(colors.orange).mix(ui.uibackground, 0.85).toHex(), + }), + attr("DIFF_DELETED", { + background: c(colors.red).mix(ui.uibackground, 0.85).toHex(), + }), + attr("DIFF_INSERTED", { + background: c(colors.green).mix(ui.uibackground, 0.85).toHex(), + }), + attr("DIFF_MODIFIED", { + background: c(colors.blue).mix(ui.uibackground, 0.85).toHex(), + }), + + // Inline hints + attr("INLINE_PARAMETER_HINT", { + background: c(ui.uibackground).lighten(0.08).toHex(), + foreground: ui.defaultalt, + }), + attr("INLINE_PARAMETER_HINT_CURRENT", { + background: c(ui.primary).mix(ui.uibackground, 0.8).toHex(), + foreground: ui.default, + }), + attr("INLINE_PARAMETER_HINT_HIGHLIGHTED", { + background: c(ui.primary).mix(ui.uibackground, 0.7).toHex(), + foreground: ui.default, + }), + + // Hyperlinks + attr("HYPERLINK_ATTRIBUTES", { + effectColor: colors.blue, + effectType: 1, + foreground: colors.blue, + }), + attr("FOLLOWED_HYPERLINK_ATTRIBUTES", { + effectColor: colors.purple, + effectType: 1, + foreground: colors.purple, + }), + + // Breadcrumbs + attr("BREADCRUMBS_CURRENT", { foreground: ui.default }), + attr("BREADCRUMBS_DEFAULT", { foreground: ui.defaultalt }), + attr("BREADCRUMBS_HOVERED", { foreground: ui.primary }), + attr("BREADCRUMBS_INACTIVE", { foreground: ui.defaultalt }), + + // Console colors + attr("CONSOLE_BLACK_OUTPUT", { foreground: isLight ? "#000000" : "#1E1E1E" }), + attr("CONSOLE_BLUE_BRIGHT_OUTPUT", { + foreground: c(colors.blue).lighten(0.1).toHex(), + }), + attr("CONSOLE_BLUE_OUTPUT", { foreground: colors.blue }), + attr("CONSOLE_CYAN_BRIGHT_OUTPUT", { + foreground: c(colors.turquoize).lighten(0.1).toHex(), + }), + attr("CONSOLE_CYAN_OUTPUT", { foreground: colors.turquoize }), + attr("CONSOLE_DARKGRAY_OUTPUT", { foreground: ui.defaultalt }), + attr("CONSOLE_ERROR_OUTPUT", { foreground: colors.red }), + attr("CONSOLE_GRAY_OUTPUT", { foreground: ui.defaultalt }), + attr("CONSOLE_GREEN_BRIGHT_OUTPUT", { + foreground: c(colors.green).lighten(0.1).toHex(), + }), + attr("CONSOLE_GREEN_OUTPUT", { foreground: colors.green }), + attr("CONSOLE_MAGENTA_BRIGHT_OUTPUT", { + foreground: c(colors.pink).lighten(0.1).toHex(), + }), + attr("CONSOLE_MAGENTA_OUTPUT", { foreground: colors.pink }), + attr("CONSOLE_NORMAL_OUTPUT", { foreground: ui.default }), + attr("CONSOLE_RED_BRIGHT_OUTPUT", { + foreground: c(colors.red).lighten(0.1).toHex(), + }), + attr("CONSOLE_RED_OUTPUT", { foreground: colors.red }), + attr("CONSOLE_SYSTEM_OUTPUT", { foreground: ui.defaultalt }), + attr("CONSOLE_USER_INPUT", { foreground: colors.green }), + attr("CONSOLE_WHITE_OUTPUT", { foreground: ui.default }), + attr("CONSOLE_YELLOW_BRIGHT_OUTPUT", { + foreground: c(colors.yellow).lighten(0.1).toHex(), + }), + attr("CONSOLE_YELLOW_OUTPUT", { foreground: colors.yellow }), + + // Log console + attr("LOG_DEBUG_OUTPUT", { foreground: ui.defaultalt }), + attr("LOG_ERROR_OUTPUT", { foreground: colors.red }), + attr("LOG_EXPIRED_ENTRY", { foreground: ui.defaultalt }), + attr("LOG_INFO_OUTPUT", { foreground: colors.blue }), + attr("LOG_WARNING_OUTPUT", { foreground: colors.orange }), + + // Debugger + attr("BREAKPOINT_ATTRIBUTES", { + background: c(colors.red).mix(ui.uibackground, 0.7).toHex(), + }), + attr("EXECUTIONPOINT_ATTRIBUTES", { + background: c(colors.yellow).mix(ui.uibackground, 0.7).toHex(), + }), + ]; + + return attributes.join("\n"); +} + +/** + * Build color options for the scheme + * + * @param theme - Theme object + * @param isLight - Whether this is a light theme + * @param isHc - Whether this is a high contrast theme + * @returns XML string of color options + */ +function buildColorOptions( + theme: Theme, + isLight?: boolean, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isHc?: boolean, +): string { + const { colors, levels, ui } = theme; + + // Helper to mix color with background for transparent effect + const mixWithBg = (color: string, alpha: number): string => { + return toHex(c(color).mix(ui.uibackground, 1 - alpha).toHex()); + }; + + const colorMap: Record = { + // VCS / Diff colors + ADDED_LINES_COLOR: toHex(colors.green), + // Bookmarks + Bookmark_mnemonic_assigned: toHex(ui.primary), + Bookmark_mnemonic_current: toHex(colors.yellow), + Bookmark_mnemonic_not_assigned: toHex(ui.defaultalt), + // Editor background and foreground + CARET_COLOR: toHex(ui.primary), + CARET_ROW_COLOR: mixWithBg( + isLight + ? c(ui.uibackground).darken(0.05).toHex() + : c(ui.uibackground).lighten(0.03).toHex(), + 1, + ), + CONSOLE_BACKGROUND_KEY: toHex(ui.uibackground), + DELETED_LINES_COLOR: toHex(levels.danger), + DIFF_SEPARATORS_BACKGROUND: toHex(ui.uibackgroundalt), + // Error / Warning / Info + ERRORS_ATTRIBUTES: toHex(levels.danger), + FILESTATUS_ADDED: toHex(colors.green), + FILESTATUS_COPIED: toHex(colors.green), + FILESTATUS_DELETED: toHex(levels.danger), + FILESTATUS_IDEA_FILESTATUS_DELETED_FROM_FILE_SYSTEM: toHex( + c(levels.danger).desaturate(0.3).toHex(), + ), + FILESTATUS_IDEA_FILESTATUS_IGNORED: toHex(ui.defaultalt), + FILESTATUS_MERGED: toHex(colors.purple), + + FILESTATUS_MODIFIED: toHex(colors.blue), + FILESTATUS_NOT_CHANGED_IMMEDIATE: toHex(colors.blue), + FILESTATUS_NOT_CHANGED_RECURSIVE: toHex(colors.blue), + FILESTATUS_SWITCHED: toHex(colors.purple), + FILESTATUS_UNKNOWN: toHex(colors.orange), + GUTTER_BACKGROUND: toHex(ui.uibackground), + // Search + IDENTIFIER_UNDER_CARET_ATTRIBUTES: mixWithBg(ui.primary, 0.2), + INDENT_GUIDE: mixWithBg(ui.default, 0.1), + INFO_ATTRIBUTES: toHex(levels.info), + LINE_NUMBER_ON_CARET_ROW_COLOR: mixWithBg(ui.default, 0.6), + LINE_NUMBERS_COLOR: mixWithBg(ui.default, 0.3), + METHOD_SEPARATORS_COLOR: toHex(ui.border), + MODIFIED_LINES_COLOR: toHex(colors.blue), + RIGHT_MARGIN_COLOR: toHex(ui.border), + "ScrollBar.Mac.hoverThumbBorderColor": mixWithBg(ui.default, 0.25), + + "ScrollBar.Mac.hoverThumbColor": mixWithBg(ui.default, 0.25), + "ScrollBar.Mac.thumbBorderColor": mixWithBg(ui.default, 0.15), + // ScrollBar (editor specific) + "ScrollBar.Mac.thumbColor": mixWithBg(ui.default, 0.15), + + SEARCH_RESULT_ATTRIBUTES: mixWithBg(colors.yellow, 0.3), + SELECTED_INDENT_GUIDE: mixWithBg(ui.default, 0.2), + SELECTION_BACKGROUND: mixWithBg(ui.primary, 0.25), + SELECTION_FOREGROUND: "", + SOFT_WRAP_SIGN_COLOR: toHex(ui.defaultalt), + + TEARLINE_COLOR: toHex(ui.border), + TEXT_SEARCH_RESULT_ATTRIBUTES: mixWithBg(colors.yellow, 0.3), + VISUAL_INDENT_GUIDE: mixWithBg(ui.default, 0.1), + + WARNING_ATTRIBUTES: toHex(levels.warning), + WHITESPACES: mixWithBg(ui.default, 0.15), + WRITE_IDENTIFIER_UNDER_CARET_ATTRIBUTES: mixWithBg(ui.primary, 0.3), + WRITE_SEARCH_RESULT_ATTRIBUTES: mixWithBg(colors.yellow, 0.4), + }; + + return Object.entries(colorMap) + .filter(([, value]) => value !== "") + .map(([name, value]) => `