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(``);
+ }
+ if (opts.background) {
+ parts.push(``);
+ }
+ if (opts.fontType !== undefined) {
+ parts.push(``);
+ }
+ if (opts.effectColor) {
+ parts.push(``);
+ }
+ if (opts.effectType !== undefined) {
+ parts.push(``);
+ }
+
+ if (parts.length === 0) {
+ return ` `;
+ }
+
+ return `
+
+ ${parts.join("\n ")}
+
+ `;
+ };
+
+ // 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]) => ` `)
+ .join("\n");
+}
+
+/**
+ * Escape special XML characters for use in attributes
+ *
+ * @param str - String to escape
+ * @returns XML-safe string
+ */
+function escapeXmlAttribute(str: string): string {
+ return str
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+}
diff --git a/src/generators/jetbrains/index.ts b/src/generators/jetbrains/index.ts
new file mode 100644
index 0000000..a56393e
--- /dev/null
+++ b/src/generators/jetbrains/index.ts
@@ -0,0 +1,605 @@
+/**
+ * JetBrains Theme Generator
+ *
+ * Main build script for generating JetBrains IDE themes.
+ * Generates a complete plugin structure that can be built with Gradle.
+ *
+ * Output structure:
+ * dist/jetbrains/
+ * ├── resources/
+ * │ └── META-INF/
+ * │ └── plugin.xml
+ * ├── themes/
+ * │ ├── bearded-theme-{slug}.theme.json
+ * │ └── bearded-theme-{slug}.xml (editor schemes)
+ * ├── build.gradle.kts
+ * ├── settings.gradle.kts
+ * ├── gradle.properties
+ * └── README.md
+ */
+
+import { chmodSync, mkdirSync, writeFileSync } from "fs";
+import { join } from "path";
+
+import { themeRegistry, ThemeRegistryEntry } from "../../shared/theme-registry";
+import { getJetBrainsVersion } from "../../version-manager";
+import { buildEditorScheme } from "./editor-scheme";
+import { generatePluginXml } from "./plugin";
+import { buildJetBrainsTheme } from "./theme";
+
+// Output directories
+const OUTPUT_DIR = "dist/jetbrains";
+const THEMES_DIR = join(OUTPUT_DIR, "themes");
+const RESOURCES_DIR = join(OUTPUT_DIR, "resources");
+const META_INF_DIR = join(RESOURCES_DIR, "META-INF");
+
+/**
+ * Main build function for JetBrains themes
+ */
+async function buildJetBrainsThemes(): Promise {
+ console.log("🎨 Building JetBrains themes...");
+
+ // Get version from versions.json
+ const version = getJetBrainsVersion();
+ console.log(`📦 Using JetBrains version: ${version}`);
+
+ // Ensure output directories exist
+ mkdirSync(THEMES_DIR, { recursive: true });
+ mkdirSync(META_INF_DIR, { recursive: true });
+
+ // Generate all theme files
+ for (const entry of themeRegistry) {
+ await generateThemeFiles(entry);
+ }
+
+ // Generate plugin.xml
+ const pluginXml = generatePluginXml(themeRegistry, version);
+ writeFileSync(join(META_INF_DIR, "plugin.xml"), pluginXml, {
+ encoding: "utf8",
+ });
+
+ // Generate Gradle build files and wrapper
+ generateGradleFiles(version);
+ generateGradleWrapper();
+
+ // Generate README
+ generateReadme();
+
+ console.log(
+ `✅ Generated ${themeRegistry.length} JetBrains themes in ${OUTPUT_DIR}`,
+ );
+ console.log(`✅ Generated plugin.xml (version ${version})`);
+ console.log("✅ Generated Gradle build files");
+ console.log("✅ Generated README.md");
+ console.log(`\n📁 JetBrains plugin ready in: ${OUTPUT_DIR}/`);
+ console.log("\n📝 To build the plugin:");
+ console.log(" cd dist/jetbrains");
+ console.log(" ./gradlew buildPlugin");
+ console.log("\n The plugin ZIP will be in build/distributions/");
+}
+
+/**
+ * Generate Gradle build files for the plugin
+ *
+ * @param version - Plugin version
+ */
+function generateGradleFiles(version: string): void {
+ // build.gradle.kts
+ const buildGradle = `plugins {
+ id("org.jetbrains.intellij.platform") version "2.10.5"
+}
+
+group = "com.beardedtheme"
+version = "${version}"
+
+repositories {
+ mavenCentral()
+ intellijPlatform {
+ defaultRepositories()
+ }
+}
+
+// Configure source sets to use our directory structure
+sourceSets {
+ main {
+ resources {
+ srcDirs("resources", "themes")
+ }
+ }
+}
+
+dependencies {
+ intellijPlatform {
+ // Target IntelliJ IDEA Community as our base IDE (works with all JetBrains IDEs)
+ // Using a stable version that has available dependencies
+ create("IC", "2024.2.1")
+
+ // Use bundled plugin verifier
+ pluginVerifier()
+ }
+}
+
+intellijPlatform {
+ pluginConfiguration {
+ name = "Bearded Theme"
+ version = "${version}"
+ description = "The theme with a long beard. A collection of carefully crafted color themes."
+ changeNotes = "See GitHub releases for changelog."
+
+ ideaVersion {
+ sinceBuild = "242"
+ untilBuild = provider { null }
+ }
+
+ vendor {
+ name = "BeardedBear"
+ email = "beardedbearbear@gmail.com"
+ url = "https://github.com/BeardedBear/bearded-theme"
+ }
+ }
+
+ publishing {
+ // Configure for JetBrains Marketplace publishing
+ // token = System.getenv("PUBLISH_TOKEN")
+ }
+
+ // Disable instrumentation since this is a theme-only plugin with no code
+ instrumentCode = false
+}
+
+tasks {
+ buildSearchableOptions {
+ enabled = false
+ }
+
+ processResources {
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
+ }
+}
+`;
+
+ writeFileSync(join(OUTPUT_DIR, "build.gradle.kts"), buildGradle, {
+ encoding: "utf8",
+ });
+
+ // settings.gradle.kts
+ const settingsGradle = `rootProject.name = "bearded-theme"
+
+pluginManagement {
+ repositories {
+ maven("https://oss.sonatype.org/content/repositories/snapshots/")
+ gradlePluginPortal()
+ }
+}
+
+dependencyResolutionManagement {
+ repositories {
+ mavenCentral()
+ }
+}
+`;
+
+ writeFileSync(join(OUTPUT_DIR, "settings.gradle.kts"), settingsGradle, {
+ encoding: "utf8",
+ });
+
+ // gradle.properties
+ const gradleProperties = `# Gradle settings
+org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
+org.gradle.caching=true
+org.gradle.parallel=true
+
+# Kotlin settings
+kotlin.stdlib.default.dependency=false
+
+# IntelliJ Platform settings
+# See https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html
+platformType=IC
+platformVersion=2024.2.1
+`;
+
+ writeFileSync(join(OUTPUT_DIR, "gradle.properties"), gradleProperties, {
+ encoding: "utf8",
+ });
+}
+
+/**
+ * Generate Gradle wrapper files
+ *
+ * Creates the gradlew, gradlew.bat scripts and gradle/wrapper directory
+ * so users don't need Gradle installed to build the plugin.
+ */
+function generateGradleWrapper(): void {
+ const wrapperDir = join(OUTPUT_DIR, "gradle", "wrapper");
+ mkdirSync(wrapperDir, { recursive: true });
+
+ // gradle-wrapper.properties
+ const wrapperProperties = `distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\\://services.gradle.org/distributions/gradle-8.13-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+`;
+
+ writeFileSync(
+ join(wrapperDir, "gradle-wrapper.properties"),
+ wrapperProperties,
+ { encoding: "utf8" },
+ );
+
+ // gradlew (Unix shell script)
+ const gradlewUnix = `#!/bin/sh
+
+#
+# Gradle start up script for POSIX systems
+#
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=\${app_path%"\${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=\${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=\${0##*/}
+APP_HOME=$( cd "\${APP_HOME:-./}" && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; #(
+ /?*) t=\${arg#)}; t=/\${t%%/*} #(
+ [ -e "$t" ] ;;
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # temporary files, so each has its own turn at the end.
+ shift
+ set -- "$@" "$arg"
+ done
+fi
+
+# Add default JVM options here.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# temporary shell commands that run inside "" and get evaluated
+# within "" by the exec below.
+# * DEFAULT_JVM_OPTS://
+set -- \\
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \\
+ -classpath "$CLASSPATH" \\
+ org.gradle.wrapper.GradleWrapperMain \\
+ "$@"
+
+# Stop when "xeli" has created that special file indicating that the initialization is complete
+# that file is a sign for us to skip the code below, which is used for initializing Gradle
+
+exec "$JAVACMD" "$@"
+`;
+
+ writeFileSync(join(OUTPUT_DIR, "gradlew"), gradlewUnix, { encoding: "utf8" });
+
+ // Make gradlew executable on Unix systems
+ try {
+ chmodSync(join(OUTPUT_DIR, "gradlew"), 0o755);
+ } catch {
+ // Ignore chmod errors on Windows
+ }
+
+ // gradlew.bat (Windows batch script)
+ const gradlewBat = `@rem
+@rem Gradle startup script for Windows
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem having the _cmd.exe return code instead.
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
+`;
+
+ writeFileSync(join(OUTPUT_DIR, "gradlew.bat"), gradlewBat, {
+ encoding: "utf8",
+ });
+
+ console.log("✅ Generated Gradle wrapper scripts");
+ console.log(
+ " ⚠️ Note: gradle-wrapper.jar must be downloaded on first build",
+ );
+}
+
+/**
+ * Generate README for the JetBrains plugin
+ */
+function generateReadme(): void {
+ const readmeContent = `# Bearded Theme for JetBrains IDEs
+
+The theme with a long beard. A collection of carefully crafted color themes for JetBrains IDEs.
+
+## Installation
+
+### From JetBrains Marketplace (Recommended)
+
+1. Open your JetBrains IDE (WebStorm, IntelliJ IDEA, PyCharm, etc.)
+2. Go to **Settings/Preferences** → **Plugins** → **Marketplace**
+3. Search for "Bearded Theme"
+4. Click **Install**
+5. Restart the IDE
+6. Go to **Settings/Preferences** → **Appearance & Behavior** → **Appearance**
+7. Select your preferred Bearded Theme from the Theme dropdown
+
+### From ZIP File (Manual Installation)
+
+1. Download the plugin ZIP file from the releases
+2. Open your JetBrains IDE
+3. Go to **Settings/Preferences** → **Plugins**
+4. Click the gear icon ⚙️ and select **Install Plugin from Disk...**
+5. Select the downloaded ZIP file
+6. Restart the IDE
+7. Select your theme in **Settings/Preferences** → **Appearance & Behavior** → **Appearance**
+
+## Building from Source
+
+### Prerequisites
+
+- Java 17 or higher
+- Gradle (wrapper included)
+
+### Build Commands
+
+\`\`\`bash
+# Build the plugin
+./gradlew buildPlugin
+
+# The plugin ZIP will be in build/distributions/
+
+# Run the plugin in a sandbox IDE for testing
+./gradlew runIde
+
+# Verify plugin compatibility
+./gradlew verifyPlugin
+\`\`\`
+
+## Available Themes
+
+${themeRegistry.map((entry) => `- Bearded Theme ${entry.name}`).join("\n")}
+
+## Theme Categories
+
+- **Arc** - Clean, modern dark themes
+- **Solarized** - Classic solarized color schemes
+- **Oceanic** - Ocean-inspired color palettes
+- **Monokai** - Monokai-inspired variants
+- **Black & Gems** - Pure black backgrounds with gem accent colors
+- **High Contrast (HC)** - Accessibility-focused themes
+- **Milkshake** - Soft, pastel light themes
+- **Coffee** - Warm, earthy tones
+- **Vivid** - Vibrant, saturated colors
+- **Aquarelle** - Watercolor-inspired themes
+- **Surprising** - Unique, unexpected color combinations
+
+## Links
+
+- [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=BeardedBear.beardedtheme)
+- [Zed Extension](https://github.com/BeardedBear/bearded-theme)
+- [GitHub Repository](https://github.com/BeardedBear/bearded-theme)
+- [Report Issues](https://github.com/BeardedBear/bearded-theme/issues)
+
+## License
+
+GNU General Public License v3.0
+
+## Author
+
+Made with ❤️ by [BeardedBear](https://github.com/BeardedBear)
+`;
+
+ writeFileSync(join(OUTPUT_DIR, "README.md"), readmeContent, {
+ encoding: "utf8",
+ });
+}
+
+/**
+ * Generate theme.json and editor scheme XML for a single theme
+ *
+ * @param entry - Theme registry entry
+ */
+async function generateThemeFiles(entry: ThemeRegistryEntry): Promise {
+ const { slug } = entry;
+
+ // Generate theme.json
+ const theme = buildJetBrainsTheme(entry);
+ const themeJson = JSON.stringify(theme, null, 2);
+ writeFileSync(join(THEMES_DIR, `bearded-theme-${slug}.theme.json`), themeJson, {
+ encoding: "utf8",
+ });
+
+ // Generate editor color scheme XML
+ const editorScheme = buildEditorScheme(entry);
+ writeFileSync(join(THEMES_DIR, `bearded-theme-${slug}.xml`), editorScheme, {
+ encoding: "utf8",
+ });
+}
+
+// Run the build
+buildJetBrainsThemes();
+
+export { buildJetBrainsThemes, generateThemeFiles };
diff --git a/src/generators/jetbrains/plugin.ts b/src/generators/jetbrains/plugin.ts
new file mode 100644
index 0000000..500ef69
--- /dev/null
+++ b/src/generators/jetbrains/plugin.ts
@@ -0,0 +1,135 @@
+/**
+ * JetBrains Plugin Manifest Generator
+ *
+ * Generates the plugin.xml file required for JetBrains IDE plugins.
+ * This file is placed in resources/META-INF/plugin.xml
+ *
+ * References:
+ * - https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html
+ * - https://plugins.jetbrains.com/docs/intellij/developing-themes.html
+ */
+
+import { ThemeRegistryEntry } from "../../shared/theme-registry";
+
+/**
+ * Generate the plugin.xml manifest file content
+ *
+ * @param themes - Array of theme registry entries
+ * @param version - Plugin version
+ * @returns XML string for plugin.xml
+ */
+export function generatePluginXml(
+ themes: ThemeRegistryEntry[],
+ version: string,
+): string {
+ const themeProviders = themes
+ .map((entry) => {
+ const themeId = escapeXml(`bearded-theme-${entry.slug}`);
+ // Path is relative to JAR root - no /themes/ prefix needed
+ const themePath = escapeXml(`/bearded-theme-${entry.slug}.theme.json`);
+
+ return ` `;
+ })
+ .join("\n");
+
+ return `
+
+ com.beardedtheme.jetbrains
+ Bearded Theme
+ ${version}
+ BeardedBear
+
+ Bearded Theme
+ The theme with a long beard. A collection of carefully crafted color themes for your IDE.
+
+ Features
+
+ - 60+ theme variants including dark, light, and high contrast options
+ - Carefully designed color palettes for reduced eye strain
+ - Consistent syntax highlighting across all supported languages
+ - Support for the new Islands UI theme style
+
+
+ Theme Categories
+
+ - Arc - Clean, modern dark themes
+ - Solarized - Classic solarized color schemes
+ - Oceanic - Ocean-inspired color palettes
+ - Monokai - Monokai-inspired variants
+ - Black & Gems - Pure black backgrounds with gem accent colors
+ - High Contrast - Accessibility-focused themes
+ - Milkshake - Soft, pastel light themes
+ - Coffee - Warm, earthy tones
+ - And many more...
+
+
+ Links
+
+ ]]>
+
+ See the GitHub Releases for full changelog.
+ ]]>
+
+
+
+ com.intellij.modules.platform
+
+
+${themeProviders}
+
+
+`;
+}
+
+/**
+ * Generate a list of theme entries for the plugin
+ *
+ * @param themes - Array of theme registry entries
+ * @returns Array of theme information objects
+ */
+export function getThemeList(
+ themes: ThemeRegistryEntry[],
+): Array<{
+ dark: boolean;
+ id: string;
+ name: string;
+ path: string;
+}> {
+ return themes.map((entry) => ({
+ dark: !entry.options.light,
+ id: `bearded-theme-${entry.slug}`,
+ name: `Bearded Theme ${entry.name}`,
+ path: `/bearded-theme-${entry.slug}.theme.json`,
+ }));
+}
+
+/**
+ * Escape special XML characters in a string
+ *
+ * @param str - String to escape
+ * @returns XML-safe string
+ */
+function escapeXml(str: string): string {
+ return str
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+}
diff --git a/src/generators/jetbrains/theme.ts b/src/generators/jetbrains/theme.ts
new file mode 100644
index 0000000..c59ef17
--- /dev/null
+++ b/src/generators/jetbrains/theme.ts
@@ -0,0 +1,107 @@
+/**
+ * JetBrains Theme Builder
+ *
+ * Generates .theme.json files for JetBrains IDEs
+ * Based on official documentation:
+ * - https://plugins.jetbrains.com/docs/intellij/themes-customize.html
+ * - https://plugins.jetbrains.com/docs/intellij/supporting-islands-theme.html
+ */
+
+import { ThemeOptions, ThemeRegistryEntry } from "../../shared/theme-registry";
+import { JetBrainsTheme } from "./types";
+import { buildJetBrainsUiColors } from "./ui";
+
+/**
+ * Build a complete JetBrains theme object
+ *
+ * @param entry - Theme registry entry
+ * @returns JetBrains theme object ready for JSON serialization
+ */
+export function buildJetBrainsTheme(entry: ThemeRegistryEntry): JetBrainsTheme {
+ const { name, options, slug, theme } = entry;
+ const isDark = !options.light;
+
+ // Build the theme object
+ const jetbrainsTheme: JetBrainsTheme = {
+ author: "BeardedBear",
+ // Named colors for reuse in the theme
+ colors: buildNamedColors(entry),
+ dark: isDark,
+
+ // Reference to editor color scheme - path is relative to JAR root
+ editorScheme: `/bearded-theme-${slug}.xml`,
+
+ name: `Bearded Theme ${name}`,
+
+ // Use Islands theme as parent for modern JetBrains UI
+ parentTheme: isDark ? "Islands Dark" : "Islands Light",
+
+ // UI component colors
+ ui: buildJetBrainsUiColors(theme, options),
+ };
+
+ return jetbrainsTheme;
+}
+
+/**
+ * Get the parent theme based on options
+ *
+ * @param options - Theme options
+ * @returns Parent theme name
+ */
+export function getParentTheme(options: ThemeOptions): string {
+ return options.light ? "Islands Light" : "Islands Dark";
+}
+
+/**
+ * Determine if a theme should be marked as dark
+ *
+ * @param options - Theme options
+ * @returns true if dark theme
+ */
+export function isDarkTheme(options: ThemeOptions): boolean {
+ return !options.light;
+}
+
+/**
+ * Build named colors that can be referenced in the UI section
+ * This makes the theme more maintainable
+ *
+ * @param entry - Theme registry entry
+ * @returns Record of named colors
+ */
+function buildNamedColors(entry: ThemeRegistryEntry): Record {
+ const { theme } = entry;
+ const { colors, levels, ui } = theme;
+
+ return {
+ // UI colors
+ background: ui.uibackground,
+ backgroundAlt: ui.uibackgroundalt,
+ backgroundMid: ui.uibackgroundmid,
+ // Syntax colors
+ blue: colors.blue,
+ border: ui.border,
+ // Level colors
+ danger: levels.danger,
+ foreground: ui.default,
+ foregroundAlt: ui.defaultalt,
+ foregroundMain: ui.defaultMain,
+ green: colors.green,
+
+ greenAlt: colors.greenAlt,
+ info: levels.info,
+ orange: colors.orange,
+ pink: colors.pink,
+ primary: ui.primary,
+ primaryAlt: ui.primaryalt,
+ purple: colors.purple,
+ red: colors.red,
+ salmon: colors.salmon,
+
+ success: levels.success,
+ turquoize: colors.turquoize,
+ warning: levels.warning,
+ yellow: colors.yellow,
+ };
+}
diff --git a/src/generators/jetbrains/types.ts b/src/generators/jetbrains/types.ts
new file mode 100644
index 0000000..28a5c46
--- /dev/null
+++ b/src/generators/jetbrains/types.ts
@@ -0,0 +1,793 @@
+/**
+ * JetBrains Theme Type Definitions
+ * These interfaces define the structure of JetBrains theme files
+ *
+ * References:
+ * - https://plugins.jetbrains.com/docs/intellij/themes-customize.html
+ * - https://plugins.jetbrains.com/docs/intellij/supporting-islands-theme.html
+ * - https://plugins.jetbrains.com/docs/intellij/themes-extras.html
+ */
+
+/**
+ * Background image configuration
+ */
+export interface JetBrainsBackgroundConfig {
+ anchor?: "bottom" | "center" | "top";
+ fill?: "plain" | "scale" | "tile";
+ image: string;
+ transparency?: number;
+}
+
+/**
+ * Icon color palette - maps original colors to new colors
+ * Can also use Actions.* and Objects.* keys
+ */
+export interface JetBrainsIconColorPalette {
+ // Standard color overrides (original color -> new color)
+ [key: string]: string;
+}
+
+/**
+ * Icon customization configuration
+ */
+export interface JetBrainsIconConfig {
+ /**
+ * Color palette overrides for icons
+ */
+ ColorPalette?: JetBrainsIconColorPalette;
+}
+
+export interface JetBrainsPluginExtension {
+ dark: boolean;
+ id: string;
+ path: string;
+}
+
+/**
+ * Plugin manifest structure for plugin.xml
+ */
+export interface JetBrainsPluginManifest {
+ changeNotes?: string;
+ depends: string[];
+ description: string;
+ extensions: JetBrainsPluginExtension[];
+ id: string;
+ name: string;
+ vendor: {
+ email: string;
+ name: string;
+ url: string;
+ };
+ version: string;
+}
+
+/**
+ * Main JetBrains theme structure
+ */
+export interface JetBrainsTheme {
+ /**
+ * Author of the theme
+ */
+ author: string;
+
+ /**
+ * Background image configuration (optional)
+ */
+ background?: JetBrainsBackgroundConfig;
+
+ /**
+ * Named colors that can be referenced in UI
+ */
+ colors?: Record;
+
+ /**
+ * Whether this is a dark theme
+ */
+ dark: boolean;
+
+ /**
+ * Path to the editor color scheme XML file (optional)
+ */
+ editorScheme?: string;
+
+ /**
+ * Empty frame background image configuration (optional)
+ */
+ emptyFrameBackground?: JetBrainsBackgroundConfig;
+
+ /**
+ * Icon customization
+ */
+ icons?: JetBrainsIconConfig;
+
+ /**
+ * Display name of the theme
+ */
+ name: string;
+
+ /**
+ * Parent theme to inherit from (for Islands theme support)
+ * Use "Islands Dark" or "Islands Light"
+ */
+ parentTheme?: string;
+
+ /**
+ * UI component colors
+ */
+ ui: JetBrainsUiColors;
+}
+
+/**
+ * UI component colors for JetBrains themes
+ * Keys follow the pattern: Component.property
+ *
+ * This is a partial list - JetBrains supports hundreds of UI keys.
+ * See: https://plugins.jetbrains.com/docs/intellij/themes-customize.html
+ */
+export interface JetBrainsUiColors {
+ // Wildcard defaults
+ "*"?: JetBrainsWildcardColors;
+
+ // Action Button
+ "ActionButton.hoverBackground"?: string;
+ "ActionButton.hoverBorderColor"?: string;
+ "ActionButton.pressedBackground"?: string;
+ "ActionButton.pressedBorderColor"?: string;
+
+ // Banner
+ "Banner.errorBackground"?: string;
+ "Banner.errorBorderColor"?: string;
+ "Banner.infoBackground"?: string;
+ "Banner.infoBorderColor"?: string;
+ "Banner.successBackground"?: string;
+ "Banner.successBorderColor"?: string;
+ "Banner.warningBackground"?: string;
+ "Banner.warningBorderColor"?: string;
+
+ // Borders
+ "Borders.color"?: string;
+ "Borders.ContrastBorderColor"?: string;
+
+ // Button
+ "Button.arc"?: number;
+ "Button.default.endBackground"?: string;
+ "Button.default.focusColor"?: string;
+ "Button.default.focusedBorderColor"?: string;
+ "Button.default.foreground"?: string;
+ "Button.default.shadowColor"?: string;
+ "Button.default.startBackground"?: string;
+ "Button.disabledText"?: string;
+ "Button.endBackground"?: string;
+ "Button.focusedBorderColor"?: string;
+ "Button.foreground"?: string;
+ "Button.shadowColor"?: string;
+ "Button.startBackground"?: string;
+
+ // Checkbox
+ "Checkbox.Background.Default"?: string;
+ "Checkbox.Background.Disabled"?: string;
+ "Checkbox.Background.Selected"?: string;
+ "Checkbox.Border.Default"?: string;
+ "Checkbox.Border.Disabled"?: string;
+ "Checkbox.Border.Selected"?: string;
+ "Checkbox.Focus.Thin.Default"?: string;
+ "Checkbox.Focus.Thin.Selected"?: string;
+ "Checkbox.Focus.Wide"?: string;
+ "Checkbox.Foreground.Disabled"?: string;
+ "Checkbox.Foreground.Selected"?: string;
+
+ // ComboBox
+ "ComboBox.ArrowButton.background"?: string;
+ "ComboBox.ArrowButton.disabledIconColor"?: string;
+ "ComboBox.ArrowButton.iconColor"?: string;
+ "ComboBox.ArrowButton.nonEditableBackground"?: string;
+ "ComboBox.background"?: string;
+ "ComboBox.disabledBackground"?: string;
+ "ComboBox.disabledForeground"?: string;
+ "ComboBox.foreground"?: string;
+ "ComboBox.modifiedItemForeground"?: string;
+ "ComboBox.nonEditableBackground"?: string;
+ "ComboBox.selectionBackground"?: string;
+ "ComboBox.selectionForeground"?: string;
+
+ // CompletionPopup
+ "CompletionPopup.background"?: string;
+ "CompletionPopup.foreground"?: string;
+ "CompletionPopup.matchForeground"?: string;
+ "CompletionPopup.selectionBackground"?: string;
+ "CompletionPopup.selectionForeground"?: string;
+ "CompletionPopup.selectionInactiveBackground"?: string;
+ "CompletionPopup.selectionInfoForeground"?: string;
+
+ // Counter
+ "Counter.background"?: string;
+ "Counter.foreground"?: string;
+
+ // Debugger
+ "Debugger.Variables.collectingDataForeground"?: string;
+ "Debugger.Variables.errorMessageForeground"?: string;
+ "Debugger.Variables.evaluatingExpressionForeground"?: string;
+ "Debugger.Variables.modifyingValueForeground"?: string;
+ "Debugger.Variables.type"?: string;
+
+ // DefaultTabs (for all tabs except TabbedPane)
+ "DefaultTabs.background"?: string;
+ "DefaultTabs.borderColor"?: string;
+ "DefaultTabs.hoverBackground"?: string;
+ "DefaultTabs.inactiveColoredFileBackground"?: string;
+ "DefaultTabs.inactiveMaskColor"?: string;
+ "DefaultTabs.underlineColor"?: string;
+ "DefaultTabs.underlinedTabBackground"?: string;
+ "DefaultTabs.underlinedTabForeground"?: string;
+ "DefaultTabs.underlineHeight"?: number;
+
+ // DragAndDrop
+ "DragAndDrop.areaBackground"?: string;
+ "DragAndDrop.areaBorderColor"?: string;
+ "DragAndDrop.areaForeground"?: string;
+
+ // Editor
+ "Editor.background"?: string;
+ "Editor.foreground"?: string;
+ "Editor.SearchField.background"?: string;
+
+ // EditorPane
+ "EditorPane.background"?: string;
+
+ // EditorTabs
+ "EditorTabs.background"?: string;
+ "EditorTabs.borderColor"?: string;
+ "EditorTabs.hoverBackground"?: string;
+ "EditorTabs.inactiveColoredFileBackground"?: string;
+ "EditorTabs.inactiveMaskColor"?: string;
+ "EditorTabs.inactiveUnderlineColor"?: string;
+ "EditorTabs.inactiveUnderlinedTabBackground"?: string;
+ "EditorTabs.underlineArc"?: number;
+ "EditorTabs.underlineColor"?: string;
+ "EditorTabs.underlinedTabBackground"?: string;
+ "EditorTabs.underlinedTabForeground"?: string;
+ "EditorTabs.underlineHeight"?: number;
+
+ // FileColor
+ "FileColor.Blue"?: string;
+ "FileColor.Green"?: string;
+ "FileColor.Orange"?: string;
+ "FileColor.Rose"?: string;
+ "FileColor.Violet"?: string;
+ "FileColor.Yellow"?: string;
+
+ // Focus
+ "Focus.borderColor"?: string;
+ "Focus.color"?: string;
+
+ // Git
+ "Git.Log.Ref.LocalBranch"?: string;
+ "Git.Log.Ref.Other"?: string;
+ "Git.Log.Ref.RemoteBranch"?: string;
+ "Git.Log.Ref.Tag"?: string;
+
+ // Group
+ "Group.disabledSeparatorColor"?: string;
+ "Group.separatorColor"?: string;
+
+ // GutterTooltip
+ "GutterTooltip.backgroundColor"?: string;
+ "GutterTooltip.borderColor"?: string;
+ "GutterTooltip.lineSeparatorColor"?: string;
+
+ // InfoPanel
+ "InfoPanel.background"?: string;
+ "InfoPanel.foreground"?: string;
+
+ // InplaceRefactoringPopup
+ "InplaceRefactoringPopup.borderColor"?: string;
+
+ // Islands (for Islands theme support)
+ "Island.arc"?: number;
+ "Island.arc.compact"?: number;
+ "Island.borderColor"?: string;
+ "Island.borderWidth"?: number;
+ "Island.borderWidth.compact"?: number;
+ "Island.inactiveAlpha"?: number;
+ Islands?: number;
+
+ // Label
+ "Label.background"?: string;
+ "Label.disabledForeground"?: string;
+ "Label.errorForeground"?: string;
+ "Label.foreground"?: string;
+ "Label.infoForeground"?: string;
+ "Label.selectedDisabledForeground"?: string;
+ "Label.selectedForeground"?: string;
+ "Label.successForeground"?: string;
+ "Label.warningForeground"?: string;
+
+ // Link
+ "Link.activeForeground"?: string;
+ "Link.hoverForeground"?: string;
+ "Link.pressedForeground"?: string;
+ "Link.secondaryForeground"?: string;
+ "Link.visitedForeground"?: string;
+
+ // List
+ "List.background"?: string;
+ "List.foreground"?: string;
+ "List.hoverBackground"?: string;
+ "List.selectionBackground"?: string;
+ "List.selectionForeground"?: string;
+ "List.selectionInactiveBackground"?: string;
+ "List.selectionInactiveForeground"?: string;
+
+ // MainMenu
+ "MainMenu.background"?: string;
+ "MainMenu.borderColor"?: string;
+ "MainMenu.disabledForeground"?: string;
+ "MainMenu.foreground"?: string;
+ "MainMenu.selectionBackground"?: string;
+ "MainMenu.selectionForeground"?: string;
+
+ // MainToolbar
+ "MainToolbar.background"?: string;
+ "MainToolbar.borderColor"?: string;
+ "MainToolbar.Dropdown.background"?: string;
+ "MainToolbar.Dropdown.hoverBackground"?: string;
+ "MainToolbar.Icon.hoverBackground"?: string;
+ "MainToolbar.Icon.pressedBackground"?: string;
+ "MainToolbar.inactiveBackground"?: string;
+ "MainToolbar.separatorColor"?: string;
+ "MainWindow.background"?: string;
+ "MainWindow.Tab.background"?: string;
+ "MainWindow.Tab.foreground"?: string;
+ "MainWindow.Tab.hoverBackground"?: string;
+ "MainWindow.Tab.inactiveUnderlineColor"?: string;
+ "MainWindow.Tab.selectedBackground"?: string;
+ "MainWindow.Tab.underlineColor"?: string;
+ "MainWindow.Tab.underlineHeight"?: number;
+
+ // MemoryIndicator
+ "MemoryIndicator.allocatedBackground"?: string;
+ "MemoryIndicator.usedBackground"?: string;
+
+ // Menu
+ "Menu.acceleratorForeground"?: string;
+ "Menu.acceleratorSelectionForeground"?: string;
+ "Menu.background"?: string;
+ "Menu.borderColor"?: string;
+ "Menu.disabledForeground"?: string;
+ "Menu.foreground"?: string;
+ "Menu.selectionBackground"?: string;
+ "Menu.selectionForeground"?: string;
+ "Menu.separatorColor"?: string;
+
+ // MenuItem
+ "MenuItem.acceleratorForeground"?: string;
+ "MenuItem.acceleratorSelectionForeground"?: string;
+ "MenuItem.background"?: string;
+ "MenuItem.disabledForeground"?: string;
+ "MenuItem.foreground"?: string;
+ "MenuItem.selectionBackground"?: string;
+ "MenuItem.selectionForeground"?: string;
+
+ // NavBar
+ "NavBar.background"?: string;
+ "NavBar.borderColor"?: string;
+
+ // NewUI (for new UI components)
+ "NewUI.activeBackground"?: string;
+
+ // NotificationError
+ "Notification.background"?: string;
+ "Notification.borderColor"?: string;
+ "Notification.errorBackground"?: string;
+ "Notification.errorBorderColor"?: string;
+ "Notification.errorForeground"?: string;
+ "Notification.foreground"?: string;
+ "Notification.linkForeground"?: string;
+ "Notification.MoreButton.background"?: string;
+ "Notification.MoreButton.foreground"?: string;
+ "Notification.ToolWindow.errorBackground"?: string;
+ "Notification.ToolWindow.errorBorderColor"?: string;
+ "Notification.ToolWindow.informativeBackground"?: string;
+ "Notification.ToolWindow.informativeBorderColor"?: string;
+ "Notification.ToolWindow.warningBackground"?: string;
+ "Notification.ToolWindow.warningBorderColor"?: string;
+
+ // Panel
+ "Panel.background"?: string;
+ "Panel.foreground"?: string;
+
+ // ParameterInfo
+ "ParameterInfo.background"?: string;
+ "ParameterInfo.borderColor"?: string;
+ "ParameterInfo.currentOverloadBackground"?: string;
+ "ParameterInfo.currentParameterForeground"?: string;
+ "ParameterInfo.disabledForeground"?: string;
+ "ParameterInfo.foreground"?: string;
+
+ // Plugins
+ "Plugins.Button.installBackground"?: string;
+ "Plugins.Button.installBorderColor"?: string;
+ "Plugins.Button.installFillBackground"?: string;
+ "Plugins.Button.installFillForeground"?: string;
+ "Plugins.Button.installFocusedBackground"?: string;
+ "Plugins.Button.installForeground"?: string;
+ "Plugins.Button.updateBackground"?: string;
+ "Plugins.Button.updateBorderColor"?: string;
+ "Plugins.Button.updateForeground"?: string;
+ "Plugins.disabledForeground"?: string;
+ "Plugins.eapTagBackground"?: string;
+ "Plugins.eapTagForeground"?: string;
+ "Plugins.hoverBackground"?: string;
+ "Plugins.lightSelectionBackground"?: string;
+ "Plugins.paidTagBackground"?: string;
+ "Plugins.paidTagForeground"?: string;
+ "Plugins.SearchField.background"?: string;
+ "Plugins.SearchField.borderColor"?: string;
+ "Plugins.SectionHeader.background"?: string;
+ "Plugins.SectionHeader.foreground"?: string;
+ "Plugins.Tab.hoverBackground"?: string;
+ "Plugins.Tab.selectedBackground"?: string;
+ "Plugins.Tab.selectedForeground"?: string;
+ "Plugins.tagBackground"?: string;
+ "Plugins.tagForeground"?: string;
+ "Plugins.trialTagBackground"?: string;
+ "Plugins.trialTagForeground"?: string;
+
+ // Popup
+ "Popup.Advertiser.background"?: string;
+ "Popup.Advertiser.borderColor"?: string;
+ "Popup.Advertiser.borderInsets"?: string;
+ "Popup.Advertiser.foreground"?: string;
+ "Popup.background"?: string;
+ "Popup.borderColor"?: string;
+ "Popup.Header.activeBackground"?: string;
+ "Popup.Header.inactiveBackground"?: string;
+ "Popup.inactiveBorderColor"?: string;
+ "Popup.Separator.foreground"?: string;
+ "Popup.Toolbar.background"?: string;
+ "Popup.Toolbar.borderColor"?: string;
+
+ // PopupMenu
+ "PopupMenu.background"?: string;
+ "PopupMenu.foreground"?: string;
+ "PopupMenu.selectionBackground"?: string;
+ "PopupMenu.selectionForeground"?: string;
+ "PopupMenu.translucentBackground"?: string;
+
+ // ProgressBar
+ "ProgressBar.backgroundColor"?: string;
+ "ProgressBar.failedColor"?: string;
+ "ProgressBar.failedEndColor"?: string;
+ "ProgressBar.foreground"?: string;
+ "ProgressBar.indeterminateEndColor"?: string;
+ "ProgressBar.indeterminateStartColor"?: string;
+ "ProgressBar.passedColor"?: string;
+ "ProgressBar.passedEndColor"?: string;
+ "ProgressBar.progressColor"?: string;
+ "ProgressBar.selectionBackground"?: string;
+ "ProgressBar.selectionForeground"?: string;
+ "ProgressBar.trackColor"?: string;
+
+ // RunWidget
+ "RunWidget.background"?: string;
+ "RunWidget.foreground"?: string;
+ "RunWidget.hoverBackground"?: string;
+ "RunWidget.iconColor"?: string;
+ "RunWidget.runningBackground"?: string;
+ "RunWidget.runningForeground"?: string;
+ "RunWidget.runningHoverBackground"?: string;
+ "RunWidget.runningIconColor"?: string;
+ "RunWidget.stopBackground"?: string;
+ "RunWidget.stopForeground"?: string;
+ "RunWidget.stopHoverBackground"?: string;
+
+ // ScrollBar
+ "ScrollBar.background"?: string;
+ "ScrollBar.hoverThumbColor"?: string;
+ "ScrollBar.hoverTrackColor"?: string;
+ "ScrollBar.Mac.hoverThumbBorderColor"?: string;
+ "ScrollBar.Mac.hoverThumbColor"?: string;
+ "ScrollBar.Mac.hoverTrackColor"?: string;
+ "ScrollBar.Mac.thumbBorderColor"?: string;
+ "ScrollBar.Mac.thumbColor"?: string;
+ "ScrollBar.Mac.trackColor"?: string;
+ "ScrollBar.Mac.Transparent.hoverThumbBorderColor"?: string;
+ "ScrollBar.Mac.Transparent.hoverThumbColor"?: string;
+ "ScrollBar.Mac.Transparent.hoverTrackColor"?: string;
+ "ScrollBar.Mac.Transparent.thumbBorderColor"?: string;
+ "ScrollBar.Mac.Transparent.thumbColor"?: string;
+ "ScrollBar.Mac.Transparent.trackColor"?: string;
+ "ScrollBar.thumbColor"?: string;
+ "ScrollBar.track"?: string;
+ "ScrollBar.trackColor"?: string;
+ "ScrollBar.Transparent.hoverThumbColor"?: string;
+ "ScrollBar.Transparent.hoverTrackColor"?: string;
+ "ScrollBar.Transparent.thumbColor"?: string;
+ "ScrollBar.Transparent.trackColor"?: string;
+
+ // SearchEverywhere
+ "SearchEverywhere.Advertiser.background"?: string;
+ "SearchEverywhere.Advertiser.foreground"?: string;
+ "SearchEverywhere.background"?: string;
+ "SearchEverywhere.Header.background"?: string;
+ "SearchEverywhere.List.separatorColor"?: string;
+ "SearchEverywhere.List.separatorForeground"?: string;
+ "SearchEverywhere.SearchField.background"?: string;
+ "SearchEverywhere.SearchField.borderColor"?: string;
+ "SearchEverywhere.Tab.selectedBackground"?: string;
+ "SearchEverywhere.Tab.selectedForeground"?: string;
+
+ // SearchField
+ "SearchField.background"?: string;
+ "SearchField.errorBackground"?: string;
+ "SearchField.errorForeground"?: string;
+
+ // SearchMatch
+ "SearchMatch.endBackground"?: string;
+ "SearchMatch.endForeground"?: string;
+ "SearchMatch.startBackground"?: string;
+ "SearchMatch.startForeground"?: string;
+
+ // SearchOption
+ "SearchOption.background"?: string;
+ "SearchOption.selectedBackground"?: string;
+
+ // SegmentedButton
+ "SegmentedButton.focusedSelectedButtonColor"?: string;
+ "SegmentedButton.selectedButtonColor"?: string;
+ "SegmentedButton.selectedEndBorderColor"?: string;
+ "SegmentedButton.selectedStartBorderColor"?: string;
+
+ // Separator
+ "Separator.foreground"?: string;
+ "Separator.separatorColor"?: string;
+
+ // Settings
+ "Settings.Spotlight.borderColor"?: string;
+
+ // SidePanel
+ "SidePanel.background"?: string;
+
+ // Slider
+ "Slider.background"?: string;
+ "Slider.buttonBorderColor"?: string;
+ "Slider.buttonColor"?: string;
+ "Slider.tickColor"?: string;
+ "Slider.trackColor"?: string;
+
+ // SpeedSearch
+ "SpeedSearch.background"?: string;
+ "SpeedSearch.borderColor"?: string;
+ "SpeedSearch.errorBackground"?: string;
+ "SpeedSearch.errorBorderColor"?: string;
+ "SpeedSearch.foreground"?: string;
+
+ // Spinner
+ "Spinner.background"?: string;
+
+ // StatusBar
+ "StatusBar.background"?: string;
+ "StatusBar.borderColor"?: string;
+ "StatusBar.hoverBackground"?: string;
+ "StatusBar.Widget.hoverBackground"?: string;
+
+ // TabbedPane
+ "TabbedPane.background"?: string;
+ "TabbedPane.borderColor"?: string;
+ "TabbedPane.contentAreaColor"?: string;
+ "TabbedPane.disabled"?: string;
+ "TabbedPane.focus"?: string;
+ "TabbedPane.focusColor"?: string;
+ "TabbedPane.foreground"?: string;
+ "TabbedPane.hoverColor"?: string;
+ "TabbedPane.tabSelectionHeight"?: number;
+ "TabbedPane.underlineColor"?: string;
+ // Table
+ "Table.alternateRowBackground"?: string;
+ "Table.background"?: string;
+ "Table.dropLineColor"?: string;
+ "Table.focusCellBackground"?: string;
+ "Table.foreground"?: string;
+ "Table.gridColor"?: string;
+
+ "Table.hoverBackground"?: string;
+ "Table.lightSelectionBackground"?: string;
+ "Table.lightSelectionForeground"?: string;
+ "Table.lightSelectionInactiveBackground"?: string;
+ "Table.lightSelectionInactiveForeground"?: string;
+ "Table.selectionBackground"?: string;
+ "Table.selectionForeground"?: string;
+ "Table.selectionInactiveBackground"?: string;
+ "Table.selectionInactiveForeground"?: string;
+ "Table.stripeColor"?: string;
+
+ // Tag
+ "Tag.background"?: string;
+ "Tag.foreground"?: string;
+
+ // TextArea
+ "TextArea.background"?: string;
+ "TextArea.caretForeground"?: string;
+ "TextArea.foreground"?: string;
+ "TextArea.inactiveBackground"?: string;
+ "TextArea.inactiveForeground"?: string;
+ "TextArea.selectionBackground"?: string;
+ "TextArea.selectionForeground"?: string;
+
+ // TextField
+ "TextField.background"?: string;
+ "TextField.borderColor"?: string;
+ "TextField.caretForeground"?: string;
+ "TextField.disabledBackground"?: string;
+ "TextField.focusedBorderColor"?: string;
+ "TextField.foreground"?: string;
+ "TextField.highlight"?: string;
+ "TextField.hoverBorderColor"?: string;
+ "TextField.inactiveBackground"?: string;
+ "TextField.inactiveForeground"?: string;
+ "TextField.placeholderForeground"?: string;
+ "TextField.selectionBackground"?: string;
+ "TextField.selectionForeground"?: string;
+
+ // TitlePane
+ "TitlePane.background"?: string;
+ "TitlePane.Button.hoverBackground"?: string;
+ "TitlePane.foreground"?: string;
+ "TitlePane.fullScreen.background"?: string;
+ "TitlePane.inactiveBackground"?: string;
+ "TitlePane.inactiveForeground"?: string;
+ "TitlePane.infoForeground"?: string;
+
+ // ToggleButton
+ "ToggleButton.background"?: string;
+ "ToggleButton.borderColor"?: string;
+ "ToggleButton.buttonColor"?: string;
+ "ToggleButton.disabledBorderColor"?: string;
+ "ToggleButton.offBackground"?: string;
+ "ToggleButton.offForeground"?: string;
+ "ToggleButton.onBackground"?: string;
+ "ToggleButton.onForeground"?: string;
+
+ // ToolBar
+ "ToolBar.background"?: string;
+ "ToolBar.borderHandleColor"?: string;
+ "ToolBar.floatingBackground"?: string;
+ "ToolBar.foreground"?: string;
+ "ToolBar.separatorColor"?: string;
+
+ // ToolTip
+ "ToolTip.Actions.background"?: string;
+ "ToolTip.Actions.foreground"?: string;
+ "ToolTip.Actions.Info.foreground"?: string;
+ "ToolTip.background"?: string;
+ "ToolTip.borderColor"?: string;
+ "ToolTip.foreground"?: string;
+ "ToolTip.infoForeground"?: string;
+ "ToolTip.separatorColor"?: string;
+ "ToolTip.shortcutForeground"?: string;
+
+ // ToolWindow
+ "ToolWindow.background"?: string;
+ "ToolWindow.Button.hoverBackground"?: string;
+ "ToolWindow.Button.selectedBackground"?: string;
+ "ToolWindow.Button.selectedForeground"?: string;
+ "ToolWindow.Header.background"?: string;
+ "ToolWindow.Header.borderColor"?: string;
+ "ToolWindow.Header.closeButton.background"?: string;
+ "ToolWindow.Header.inactiveBackground"?: string;
+ "ToolWindow.HeaderCloseButton.background"?: string;
+ "ToolWindow.HeaderTab.hoverBackground"?: string;
+ "ToolWindow.HeaderTab.hoverInactiveBackground"?: string;
+ "ToolWindow.HeaderTab.selectedBackground"?: string;
+ "ToolWindow.HeaderTab.selectedInactiveBackground"?: string;
+ "ToolWindow.HeaderTab.underlineColor"?: string;
+ "ToolWindow.HeaderTab.underlinedTabBackground"?: string;
+ "ToolWindow.HeaderTab.underlinedTabForeground"?: string;
+ "ToolWindow.HeaderTab.underlinedTabInactiveBackground"?: string;
+ "ToolWindow.HeaderTab.underlinedTabInactiveForeground"?: string;
+ "ToolWindow.HeaderTab.underlineHeight"?: number;
+ "ToolWindow.Stripe.background"?: string;
+ "ToolWindow.Stripe.borderColor"?: string;
+
+ // Tree
+ "Tree.background"?: string;
+ "Tree.errorForeground"?: string;
+ "Tree.foreground"?: string;
+ "Tree.hoverBackground"?: string;
+ "Tree.modifiedItemForeground"?: string;
+ "Tree.rowHeight"?: number;
+ "Tree.selectionBackground"?: string;
+ "Tree.selectionForeground"?: string;
+ "Tree.selectionInactiveBackground"?: string;
+
+ // ValidationTooltip
+ "ValidationTooltip.errorBackground"?: string;
+ "ValidationTooltip.errorBorderColor"?: string;
+ "ValidationTooltip.warningBackground"?: string;
+ "ValidationTooltip.warningBorderColor"?: string;
+
+ // VersionControl
+ "VersionControl.FileHistory.Commit.otherBranchBackground"?: string;
+ "VersionControl.FileHistory.Commit.selectedBranchBackground"?: string;
+ "VersionControl.GitCommits.graphColor"?: string;
+ "VersionControl.GitLog.headIconColor"?: string;
+ "VersionControl.GitLog.localBranchIconColor"?: string;
+ "VersionControl.GitLog.otherIconColor"?: string;
+ "VersionControl.GitLog.remoteBranchIconColor"?: string;
+ "VersionControl.GitLog.tagIconColor"?: string;
+ "VersionControl.HgLog.bookmarkIconColor"?: string;
+ "VersionControl.HgLog.branchIconColor"?: string;
+ "VersionControl.HgLog.closedBranchIconColor"?: string;
+ "VersionControl.HgLog.headIconColor"?: string;
+ "VersionControl.HgLog.localTagIconColor"?: string;
+ "VersionControl.HgLog.mqTagIconColor"?: string;
+ "VersionControl.HgLog.tagIconColor"?: string;
+ "VersionControl.HgLog.tipIconColor"?: string;
+ "VersionControl.Log.Commit.currentBranchBackground"?: string;
+ "VersionControl.Log.Commit.hoveredBackground"?: string;
+ "VersionControl.Log.Commit.unmatchedForeground"?: string;
+ "VersionControl.Ref.background"?: string;
+ "VersionControl.Ref.backgroundBase"?: string;
+ "VersionControl.RefLabel.background"?: string;
+ "VersionControl.RefLabel.backgroundBase"?: string;
+ "VersionControl.RefLabel.foreground"?: string;
+
+ // WelcomeScreen
+ "WelcomeScreen.background"?: string;
+ "WelcomeScreen.borderColor"?: string;
+ "WelcomeScreen.captionBackground"?: string;
+ "WelcomeScreen.captionForeground"?: string;
+ "WelcomeScreen.Details.background"?: string;
+ "WelcomeScreen.footerBackground"?: string;
+ "WelcomeScreen.footerForeground"?: string;
+ "WelcomeScreen.groupIconBorderColor"?: string;
+ "WelcomeScreen.headerBackground"?: string;
+ "WelcomeScreen.headerForeground"?: string;
+ "WelcomeScreen.Projects.actions.background"?: string;
+ "WelcomeScreen.Projects.actions.selectionBackground"?: string;
+ "WelcomeScreen.Projects.background"?: string;
+ "WelcomeScreen.Projects.selectionBackground"?: string;
+ "WelcomeScreen.Projects.selectionInactiveBackground"?: string;
+ "WelcomeScreen.separatorColor"?: string;
+ "WelcomeScreen.SidePanel.background"?: string;
+
+ // Window
+ "window.border"?: string;
+}
+
+/**
+ * Wildcard colors (applied to all components)
+ */
+export interface JetBrainsWildcardColors {
+ acceleratorForeground?: string;
+ acceleratorSelectionForeground?: string;
+ background?: string;
+ borderColor?: string;
+ caretForeground?: string;
+ disabledBackground?: string;
+ disabledBorderColor?: string;
+ disabledForeground?: string;
+ disabledText?: string;
+ errorBorderColor?: string;
+ errorForeground?: string;
+ focusColor?: string;
+ focusedBorderColor?: string;
+ foreground?: string;
+ hoverBackground?: string;
+ hoverBorderColor?: string;
+ inactiveBackground?: string;
+ inactiveForeground?: string;
+ infoForeground?: string;
+ lightSelectionBackground?: string;
+ lightSelectionForeground?: string;
+ modifiedItemForeground?: string;
+ pressedBackground?: string;
+ pressedBorderColor?: string;
+ selectionBackground?: string;
+ selectionForeground?: string;
+ selectionInactiveBackground?: string;
+ selectionInactiveForeground?: string;
+ separatorColor?: string;
+ warningBorderColor?: string;
+ warningForeground?: string;
+}
diff --git a/src/generators/jetbrains/ui.ts b/src/generators/jetbrains/ui.ts
new file mode 100644
index 0000000..e56db76
--- /dev/null
+++ b/src/generators/jetbrains/ui.ts
@@ -0,0 +1,732 @@
+/**
+ * JetBrains UI Color Mappings
+ *
+ * Maps Bearded Theme colors to JetBrains UI component colors.
+ * Based on official JetBrains theme documentation:
+ * - https://plugins.jetbrains.com/docs/intellij/themes-customize.html
+ * - https://plugins.jetbrains.com/docs/intellij/supporting-islands-theme.html
+ */
+
+import { colord as c } from "colord";
+
+import { ThemeOptions } from "../../shared/theme-registry";
+import { Theme } from "../../shared/types";
+import { JetBrainsUiColors } from "./types";
+import { transparent } from "./utils";
+
+/**
+ * Build JetBrains UI colors from a Bearded Theme
+ *
+ * @param theme - The source theme
+ * @param options - Theme options (light, hc, etc.)
+ * @returns JetBrains UI color configuration
+ */
+export function buildJetBrainsUiColors(
+ theme: Theme,
+ options: ThemeOptions,
+): JetBrainsUiColors {
+ const { hc, light } = options;
+ const { colors, levels, ui } = theme;
+
+ // Helper functions
+ const alpha = (color: string, a: number): string =>
+ c(color).alpha(a).toHex();
+
+ const lightenOrDarken = (color: string, amount: number): string =>
+ light ? c(color).darken(amount).toHex() : c(color).lighten(amount).toHex();
+
+ const hoverBg = lightenOrDarken(ui.uibackground, 0.05);
+ const selectedBg = alpha(ui.primary, 0.2);
+ const activeBg = alpha(ui.primary, 0.3);
+ const borderColor = ui.border;
+ const inputBg = light
+ ? c(ui.uibackground).lighten(0.02).toHex()
+ : c(ui.uibackground).lighten(0.03).toHex();
+
+ return {
+ // Wildcard defaults (applied to all components)
+ "*": {
+ acceleratorForeground: ui.defaultalt,
+ acceleratorSelectionForeground: ui.default,
+ background: ui.uibackground,
+ borderColor: borderColor,
+ caretForeground: ui.primary,
+ disabledBackground: alpha(ui.uibackground, 0.6),
+ disabledBorderColor: alpha(borderColor, 0.5),
+ disabledForeground: alpha(ui.default, 0.4),
+ disabledText: alpha(ui.default, 0.4),
+ errorBorderColor: levels.danger,
+ errorForeground: levels.danger,
+ focusColor: alpha(ui.primary, 0.5),
+ focusedBorderColor: ui.primary,
+ foreground: ui.default,
+ hoverBackground: hoverBg,
+ hoverBorderColor: lightenOrDarken(borderColor, 0.1),
+ inactiveBackground: ui.uibackgroundalt,
+ inactiveForeground: ui.defaultalt,
+ infoForeground: levels.info,
+ lightSelectionBackground: alpha(ui.primary, 0.15),
+ lightSelectionForeground: ui.default,
+ modifiedItemForeground: levels.info,
+ pressedBackground: activeBg,
+ pressedBorderColor: ui.primary,
+ selectionBackground: selectedBg,
+ selectionForeground: ui.default,
+ selectionInactiveBackground: alpha(ui.primary, 0.1),
+ selectionInactiveForeground: ui.default,
+ separatorColor: borderColor,
+ warningBorderColor: levels.warning,
+ warningForeground: levels.warning,
+ },
+
+ // Action Button
+ "ActionButton.hoverBackground": hoverBg,
+ "ActionButton.hoverBorderColor": transparent(borderColor),
+ "ActionButton.pressedBackground": activeBg,
+ "ActionButton.pressedBorderColor": transparent(borderColor),
+
+ // Banner
+ "Banner.errorBackground": alpha(levels.danger, 0.15),
+ "Banner.errorBorderColor": alpha(levels.danger, 0.5),
+ "Banner.infoBackground": alpha(levels.info, 0.15),
+ "Banner.infoBorderColor": alpha(levels.info, 0.5),
+ "Banner.successBackground": alpha(levels.success, 0.15),
+ "Banner.successBorderColor": alpha(levels.success, 0.5),
+ "Banner.warningBackground": alpha(levels.warning, 0.15),
+ "Banner.warningBorderColor": alpha(levels.warning, 0.5),
+
+ // Borders
+ "Borders.color": borderColor,
+ "Borders.ContrastBorderColor": hc
+ ? ui.default
+ : lightenOrDarken(borderColor, 0.1),
+
+ // Button
+ "Button.arc": 6,
+ "Button.default.endBackground": ui.primary,
+ "Button.default.focusColor": alpha(ui.primary, 0.5),
+ "Button.default.focusedBorderColor": c(ui.primary).lighten(0.2).toHex(),
+ "Button.default.foreground": light
+ ? "#FFFFFF"
+ : c(ui.primary).isDark()
+ ? "#FFFFFF"
+ : "#000000",
+ "Button.default.shadowColor": transparent(ui.uibackground),
+ "Button.default.startBackground": ui.primary,
+ "Button.disabledText": alpha(ui.default, 0.4),
+ "Button.endBackground": ui.uibackgroundalt,
+ "Button.focusedBorderColor": ui.primary,
+ "Button.foreground": ui.default,
+ "Button.shadowColor": transparent(ui.uibackground),
+ "Button.startBackground": ui.uibackgroundalt,
+
+ // Checkbox
+ "Checkbox.Background.Default": inputBg,
+ "Checkbox.Background.Disabled": alpha(inputBg, 0.5),
+ "Checkbox.Background.Selected": ui.primary,
+ "Checkbox.Border.Default": borderColor,
+ "Checkbox.Border.Disabled": alpha(borderColor, 0.5),
+ "Checkbox.Border.Selected": ui.primary,
+ "Checkbox.Focus.Thin.Default": alpha(ui.primary, 0.5),
+ "Checkbox.Focus.Thin.Selected": alpha(ui.primary, 0.5),
+ "Checkbox.Focus.Wide": alpha(ui.primary, 0.3),
+ "Checkbox.Foreground.Disabled": alpha(ui.default, 0.4),
+ "Checkbox.Foreground.Selected": light
+ ? "#FFFFFF"
+ : c(ui.primary).isDark()
+ ? "#FFFFFF"
+ : "#000000",
+
+ // ComboBox
+ "ComboBox.ArrowButton.background": inputBg,
+ "ComboBox.ArrowButton.disabledIconColor": alpha(ui.default, 0.3),
+ "ComboBox.ArrowButton.iconColor": ui.defaultalt,
+ "ComboBox.ArrowButton.nonEditableBackground": inputBg,
+ "ComboBox.background": inputBg,
+ "ComboBox.disabledBackground": alpha(inputBg, 0.5),
+ "ComboBox.disabledForeground": alpha(ui.default, 0.4),
+ "ComboBox.foreground": ui.default,
+ "ComboBox.modifiedItemForeground": levels.info,
+ "ComboBox.nonEditableBackground": inputBg,
+ "ComboBox.selectionBackground": selectedBg,
+ "ComboBox.selectionForeground": ui.default,
+
+ // CompletionPopup
+ "CompletionPopup.background": ui.uibackgroundmid,
+ "CompletionPopup.foreground": ui.default,
+ "CompletionPopup.matchForeground": ui.primary,
+ "CompletionPopup.selectionBackground": selectedBg,
+ "CompletionPopup.selectionForeground": ui.default,
+ "CompletionPopup.selectionInactiveBackground": alpha(ui.primary, 0.1),
+ "CompletionPopup.selectionInfoForeground": ui.defaultalt,
+
+ // Counter
+ "Counter.background": ui.primary,
+ "Counter.foreground": light
+ ? "#FFFFFF"
+ : c(ui.primary).isDark()
+ ? "#FFFFFF"
+ : "#000000",
+
+ // Debugger
+ "Debugger.Variables.collectingDataForeground": ui.defaultalt,
+ "Debugger.Variables.errorMessageForeground": levels.danger,
+ "Debugger.Variables.evaluatingExpressionForeground": levels.info,
+ "Debugger.Variables.modifyingValueForeground": levels.warning,
+ "Debugger.Variables.type": colors.purple,
+
+ // DefaultTabs
+ "DefaultTabs.background": ui.uibackgroundalt,
+ "DefaultTabs.borderColor": borderColor,
+ "DefaultTabs.hoverBackground": hoverBg,
+ "DefaultTabs.inactiveColoredFileBackground": transparent(ui.uibackground),
+ "DefaultTabs.inactiveMaskColor": transparent(ui.uibackground),
+ "DefaultTabs.underlineColor": ui.primary,
+ "DefaultTabs.underlinedTabBackground": ui.uibackground,
+ "DefaultTabs.underlinedTabForeground": ui.default,
+ "DefaultTabs.underlineHeight": 3,
+
+ // DragAndDrop
+ "DragAndDrop.areaBackground": alpha(ui.primary, 0.1),
+ "DragAndDrop.areaBorderColor": ui.primary,
+ "DragAndDrop.areaForeground": ui.primary,
+
+ // Editor
+ "Editor.background": ui.uibackground,
+ "Editor.foreground": ui.default,
+ "Editor.SearchField.background": inputBg,
+
+ // EditorPane
+ "EditorPane.background": ui.uibackground,
+
+ // EditorTabs
+ "EditorTabs.background": ui.uibackgroundalt,
+ "EditorTabs.borderColor": borderColor,
+ "EditorTabs.hoverBackground": hoverBg,
+ "EditorTabs.inactiveColoredFileBackground": transparent(ui.uibackground),
+ "EditorTabs.inactiveMaskColor": transparent(ui.uibackground),
+ "EditorTabs.inactiveUnderlineColor": alpha(ui.primary, 0.5),
+ "EditorTabs.inactiveUnderlinedTabBackground": ui.uibackgroundmid,
+ "EditorTabs.inactiveUnderlinedTabBorderColor": alpha(ui.primary, 0.5),
+ "EditorTabs.underlineArc": 0,
+ "EditorTabs.underlineColor": ui.primary,
+ // Islands-specific tab colors
+ "EditorTabs.underlinedBorderColor": ui.primary,
+ "EditorTabs.underlinedTabBackground": ui.uibackground,
+
+ "EditorTabs.underlinedTabForeground": ui.default,
+ "EditorTabs.underlineHeight": 3,
+ // FileColor
+ "FileColor.Blue": alpha(colors.blue, 0.15),
+ "FileColor.Green": alpha(colors.green, 0.15),
+ "FileColor.Orange": alpha(colors.orange, 0.15),
+ "FileColor.Rose": alpha(colors.pink, 0.15),
+
+ "FileColor.Violet": alpha(colors.purple, 0.15),
+ "FileColor.Yellow": alpha(colors.yellow, 0.15),
+
+ // Focus
+ "Focus.borderColor": ui.primary,
+ "Focus.color": alpha(ui.primary, 0.5),
+ // Git
+ "Git.Log.Ref.LocalBranch": colors.green,
+ "Git.Log.Ref.Other": colors.purple,
+
+ "Git.Log.Ref.RemoteBranch": colors.turquoize,
+ "Git.Log.Ref.Tag": colors.yellow,
+
+ // Group
+ "Group.disabledSeparatorColor": alpha(borderColor, 0.5),
+ "Group.separatorColor": borderColor,
+ // GutterTooltip
+ "GutterTooltip.backgroundColor": ui.uibackgroundmid,
+
+ "GutterTooltip.borderColor": borderColor,
+ "GutterTooltip.lineSeparatorColor": borderColor,
+
+ // InfoPanel
+ "InfoPanel.background": ui.uibackgroundalt,
+
+ "InfoPanel.foreground": ui.default,
+ // InplaceRefactoringPopup
+ "InplaceRefactoringPopup.borderColor": ui.primary,
+ "Island.arc": 20,
+ "Island.arc.compact": 16,
+ "Island.borderColor": ui.uibackground,
+ "Island.borderWidth": 5,
+ "Island.borderWidth.compact": 4,
+ "Island.inactiveAlpha": 0.44,
+ // Islands Theme Support
+ // See: https://plugins.jetbrains.com/docs/intellij/supporting-islands-theme.html
+ Islands: 1,
+
+ // Label
+ "Label.background": ui.uibackground,
+ "Label.disabledForeground": alpha(ui.default, 0.4),
+ "Label.errorForeground": levels.danger,
+ "Label.foreground": ui.default,
+ "Label.infoForeground": levels.info,
+
+ "Label.selectedDisabledForeground": alpha(ui.default, 0.4),
+ "Label.selectedForeground": ui.default,
+ "Label.successForeground": levels.success,
+ "Label.warningForeground": levels.warning,
+ // Link
+ "Link.activeForeground": c(ui.primary).lighten(0.1).toHex(),
+ "Link.hoverForeground": c(ui.primary).lighten(0.1).toHex(),
+ "Link.pressedForeground": c(ui.primary).darken(0.1).toHex(),
+
+ "Link.secondaryForeground": ui.defaultalt,
+ "Link.visitedForeground": colors.purple,
+ // List
+ "List.background": ui.uibackground,
+ "List.foreground": ui.default,
+ "List.hoverBackground": hoverBg,
+ "List.selectionBackground": selectedBg,
+
+ "List.selectionForeground": ui.default,
+ "List.selectionInactiveBackground": alpha(ui.primary, 0.1),
+ "List.selectionInactiveForeground": ui.default,
+ // MainMenu
+ "MainMenu.background": ui.uibackgroundalt,
+ "MainMenu.borderColor": borderColor,
+ "MainMenu.disabledForeground": alpha(ui.default, 0.4),
+ "MainMenu.foreground": ui.default,
+ "MainMenu.selectionBackground": selectedBg,
+ "MainMenu.selectionForeground": ui.default,
+ // MainToolbar
+ "MainToolbar.background": ui.uibackgroundalt,
+ "MainToolbar.borderColor": transparent(borderColor),
+ "MainToolbar.Dropdown.background": ui.uibackgroundalt,
+ "MainToolbar.Dropdown.hoverBackground": hoverBg,
+ "MainToolbar.Icon.hoverBackground": hoverBg,
+ "MainToolbar.Icon.pressedBackground": activeBg,
+ "MainToolbar.inactiveBackground": ui.uibackgroundalt,
+
+ "MainToolbar.separatorColor": borderColor,
+ "MainWindow.background": lightenOrDarken(ui.uibackgroundalt, 0.05),
+
+ "MainWindow.Tab.background": ui.uibackgroundalt,
+ "MainWindow.Tab.foreground": ui.defaultalt,
+ "MainWindow.Tab.hoverBackground": hoverBg,
+ "MainWindow.Tab.inactiveUnderlineColor": alpha(ui.primary, 0.5),
+ "MainWindow.Tab.selectedBackground": ui.uibackground,
+ "MainWindow.Tab.underlineColor": ui.primary,
+ "MainWindow.Tab.underlineHeight": 3,
+ // MemoryIndicator
+ "MemoryIndicator.allocatedBackground": alpha(ui.primary, 0.2),
+ "MemoryIndicator.usedBackground": ui.primary,
+
+ // Menu
+ "Menu.acceleratorForeground": ui.defaultalt,
+ "Menu.acceleratorSelectionForeground": ui.default,
+ "Menu.background": ui.uibackgroundmid,
+ "Menu.borderColor": borderColor,
+ "Menu.disabledForeground": alpha(ui.default, 0.4),
+ "Menu.foreground": ui.default,
+ "Menu.selectionBackground": selectedBg,
+
+ "Menu.selectionForeground": ui.default,
+ "Menu.separatorColor": borderColor,
+
+ // MenuItem
+ "MenuItem.acceleratorForeground": ui.defaultalt,
+ "MenuItem.acceleratorSelectionForeground": ui.default,
+ "MenuItem.background": ui.uibackgroundmid,
+ "MenuItem.disabledForeground": alpha(ui.default, 0.4),
+ "MenuItem.foreground": ui.default,
+ "MenuItem.selectionBackground": selectedBg,
+ "MenuItem.selectionForeground": ui.default,
+ // NavBar
+ "NavBar.background": ui.uibackgroundalt,
+ "NavBar.borderColor": borderColor,
+ // Notification
+ "Notification.background": ui.uibackgroundmid,
+ "Notification.borderColor": borderColor,
+ "Notification.errorBackground": alpha(levels.danger, 0.15),
+ "Notification.errorBorderColor": levels.danger,
+ "Notification.errorForeground": ui.default,
+ "Notification.foreground": ui.default,
+
+ "Notification.linkForeground": ui.primary,
+ "Notification.MoreButton.background": ui.uibackgroundalt,
+
+ "Notification.MoreButton.foreground": ui.default,
+ "Notification.ToolWindow.errorBackground": alpha(levels.danger, 0.15),
+ "Notification.ToolWindow.errorBorderColor": levels.danger,
+ "Notification.ToolWindow.informativeBackground": alpha(levels.info, 0.15),
+ "Notification.ToolWindow.informativeBorderColor": levels.info,
+ "Notification.ToolWindow.warningBackground": alpha(levels.warning, 0.15),
+
+ "Notification.ToolWindow.warningBorderColor": levels.warning,
+ // Panel
+ "Panel.background": ui.uibackground,
+ "Panel.foreground": ui.default,
+ // ParameterInfo
+ "ParameterInfo.background": ui.uibackgroundmid,
+ "ParameterInfo.borderColor": borderColor,
+ "ParameterInfo.currentOverloadBackground": alpha(ui.primary, 0.1),
+ "ParameterInfo.currentParameterForeground": ui.primary,
+ "ParameterInfo.disabledForeground": alpha(ui.default, 0.4),
+ "ParameterInfo.foreground": ui.default,
+ // Plugins
+ "Plugins.Button.installBackground": alpha(levels.success, 0.15),
+ "Plugins.Button.installBorderColor": levels.success,
+ "Plugins.Button.installFillBackground": levels.success,
+ "Plugins.Button.installFillForeground": "#FFFFFF",
+ "Plugins.Button.installFocusedBackground": alpha(levels.success, 0.25),
+ "Plugins.Button.installForeground": levels.success,
+ "Plugins.Button.updateBackground": alpha(ui.primary, 0.15),
+ "Plugins.Button.updateBorderColor": ui.primary,
+ "Plugins.Button.updateForeground": ui.primary,
+ "Plugins.disabledForeground": alpha(ui.default, 0.4),
+ "Plugins.eapTagBackground": alpha(colors.orange, 0.2),
+ "Plugins.eapTagForeground": colors.orange,
+ "Plugins.hoverBackground": hoverBg,
+ "Plugins.lightSelectionBackground": alpha(ui.primary, 0.1),
+ "Plugins.paidTagBackground": alpha(colors.green, 0.2),
+ "Plugins.paidTagForeground": colors.green,
+ "Plugins.SearchField.background": inputBg,
+ "Plugins.SearchField.borderColor": borderColor,
+
+ "Plugins.SectionHeader.background": ui.uibackgroundalt,
+ "Plugins.SectionHeader.foreground": ui.default,
+ "Plugins.Tab.hoverBackground": hoverBg,
+ "Plugins.Tab.selectedBackground": selectedBg,
+ "Plugins.Tab.selectedForeground": ui.default,
+ "Plugins.tagBackground": alpha(ui.primary, 0.15),
+ "Plugins.tagForeground": ui.primary,
+ "Plugins.trialTagBackground": alpha(colors.purple, 0.2),
+ "Plugins.trialTagForeground": colors.purple,
+ // Popup
+ "Popup.Advertiser.background": ui.uibackgroundalt,
+ "Popup.Advertiser.borderColor": borderColor,
+ "Popup.Advertiser.borderInsets": "1,1,1,1",
+
+ "Popup.Advertiser.foreground": ui.defaultalt,
+ "Popup.background": ui.uibackgroundmid,
+ "Popup.borderColor": borderColor,
+ "Popup.Header.activeBackground": ui.uibackgroundalt,
+ "Popup.Header.inactiveBackground": ui.uibackgroundalt,
+
+ "Popup.inactiveBorderColor": alpha(borderColor, 0.5),
+ "Popup.Separator.foreground": borderColor,
+ "Popup.Toolbar.background": ui.uibackgroundalt,
+ "Popup.Toolbar.borderColor": borderColor,
+ // PopupMenu
+ "PopupMenu.background": ui.uibackgroundmid,
+ "PopupMenu.foreground": ui.default,
+ "PopupMenu.selectionBackground": selectedBg,
+ "PopupMenu.selectionForeground": ui.default,
+ "PopupMenu.translucentBackground": alpha(ui.uibackgroundmid, 0.95),
+ // ProgressBar
+ "ProgressBar.backgroundColor": ui.uibackgroundalt,
+ "ProgressBar.failedColor": levels.danger,
+ "ProgressBar.failedEndColor": c(levels.danger).lighten(0.1).toHex(),
+
+ "ProgressBar.foreground": ui.primary,
+ "ProgressBar.indeterminateEndColor": c(ui.primary).lighten(0.15).toHex(),
+ "ProgressBar.indeterminateStartColor": ui.primary,
+ "ProgressBar.passedColor": levels.success,
+ "ProgressBar.passedEndColor": c(levels.success).lighten(0.1).toHex(),
+ "ProgressBar.progressColor": ui.primary,
+ "ProgressBar.selectionBackground": ui.uibackgroundalt,
+ "ProgressBar.selectionForeground": ui.default,
+ "ProgressBar.trackColor": ui.uibackgroundalt,
+ // RunWidget
+ "RunWidget.background": ui.uibackgroundalt,
+ "RunWidget.foreground": ui.default,
+
+ "RunWidget.hoverBackground": hoverBg,
+ "RunWidget.iconColor": levels.success,
+ "RunWidget.runningBackground": alpha(levels.success, 0.15),
+ "RunWidget.runningForeground": ui.default,
+ "RunWidget.runningHoverBackground": alpha(levels.success, 0.25),
+ "RunWidget.runningIconColor": levels.success,
+ "RunWidget.stopBackground": alpha(levels.danger, 0.15),
+ "RunWidget.stopForeground": ui.default,
+ "RunWidget.stopHoverBackground": alpha(levels.danger, 0.25),
+ // ScrollBar
+ "ScrollBar.background": transparent(ui.uibackground),
+ "ScrollBar.hoverThumbColor": alpha(ui.default, 0.3),
+ "ScrollBar.hoverTrackColor": transparent(ui.uibackground),
+ "ScrollBar.Mac.hoverThumbBorderColor": transparent(ui.uibackground),
+ "ScrollBar.Mac.hoverThumbColor": alpha(ui.default, 0.3),
+ "ScrollBar.Mac.hoverTrackColor": transparent(ui.uibackground),
+ "ScrollBar.Mac.thumbBorderColor": transparent(ui.uibackground),
+ "ScrollBar.Mac.thumbColor": alpha(ui.default, 0.15),
+ "ScrollBar.Mac.trackColor": transparent(ui.uibackground),
+ "ScrollBar.Mac.Transparent.hoverThumbBorderColor":
+ transparent(ui.uibackground),
+ "ScrollBar.Mac.Transparent.hoverThumbColor": alpha(ui.default, 0.3),
+ "ScrollBar.Mac.Transparent.hoverTrackColor": transparent(ui.uibackground),
+ "ScrollBar.Mac.Transparent.thumbBorderColor": transparent(ui.uibackground),
+
+ "ScrollBar.Mac.Transparent.thumbColor": alpha(ui.default, 0.15),
+ "ScrollBar.Mac.Transparent.trackColor": transparent(ui.uibackground),
+ "ScrollBar.thumbColor": alpha(ui.default, 0.15),
+ "ScrollBar.track": transparent(ui.uibackground),
+ "ScrollBar.trackColor": transparent(ui.uibackground),
+ "ScrollBar.Transparent.hoverThumbColor": alpha(ui.default, 0.3),
+ "ScrollBar.Transparent.hoverTrackColor": transparent(ui.uibackground),
+ "ScrollBar.Transparent.thumbColor": alpha(ui.default, 0.15),
+ "ScrollBar.Transparent.trackColor": transparent(ui.uibackground),
+ // SearchEverywhere
+ "SearchEverywhere.Advertiser.background": ui.uibackgroundalt,
+
+ "SearchEverywhere.Advertiser.foreground": ui.defaultalt,
+ "SearchEverywhere.background": ui.uibackgroundmid,
+ "SearchEverywhere.Header.background": ui.uibackgroundalt,
+
+ "SearchEverywhere.List.separatorColor": borderColor,
+ "SearchEverywhere.List.separatorForeground": ui.defaultalt,
+ "SearchEverywhere.SearchField.background": inputBg,
+ "SearchEverywhere.SearchField.borderColor": borderColor,
+
+ "SearchEverywhere.Tab.selectedBackground": selectedBg,
+ "SearchEverywhere.Tab.selectedForeground": ui.default,
+
+ // SearchField
+ "SearchField.background": inputBg,
+ "SearchField.errorBackground": alpha(levels.danger, 0.15),
+ "SearchField.errorForeground": levels.danger,
+ // SearchMatch
+ "SearchMatch.endBackground": alpha(colors.yellow, 0.3),
+
+ "SearchMatch.endForeground": ui.default,
+ "SearchMatch.startBackground": alpha(colors.yellow, 0.3),
+
+ "SearchMatch.startForeground": ui.default,
+
+ // SearchOption
+ "SearchOption.background": ui.uibackgroundalt,
+
+ "SearchOption.selectedBackground": selectedBg,
+ // SegmentedButton
+ "SegmentedButton.focusedSelectedButtonColor": ui.primary,
+ "SegmentedButton.selectedButtonColor": selectedBg,
+ "SegmentedButton.selectedEndBorderColor": ui.primary,
+ "SegmentedButton.selectedStartBorderColor": ui.primary,
+
+ // Separator
+ "Separator.foreground": borderColor,
+ "Separator.separatorColor": borderColor,
+ // Settings
+ "Settings.Spotlight.borderColor": ui.primary,
+ // SidePanel
+ "SidePanel.background": ui.uibackgroundalt,
+ // Slider
+ "Slider.background": ui.uibackground,
+
+ "Slider.buttonBorderColor": borderColor,
+
+ "Slider.buttonColor": ui.uibackgroundalt,
+ "Slider.tickColor": ui.defaultalt,
+ "Slider.trackColor": ui.uibackgroundalt,
+ // SpeedSearch
+ "SpeedSearch.background": ui.uibackgroundmid,
+
+ "SpeedSearch.borderColor": ui.primary,
+ "SpeedSearch.errorBackground": alpha(levels.danger, 0.15),
+ "SpeedSearch.errorBorderColor": levels.danger,
+ "SpeedSearch.foreground": ui.default,
+ // Spinner
+ "Spinner.background": inputBg,
+ // StatusBar
+ "StatusBar.background": ui.uibackgroundalt,
+ "StatusBar.borderColor": transparent(borderColor),
+ "StatusBar.hoverBackground": hoverBg,
+ "StatusBar.Widget.hoverBackground": hoverBg,
+ // TabbedPane
+ "TabbedPane.background": ui.uibackgroundalt,
+ "TabbedPane.borderColor": borderColor,
+ "TabbedPane.contentAreaColor": ui.uibackground,
+ "TabbedPane.disabled": alpha(ui.default, 0.4),
+ "TabbedPane.focus": ui.primary,
+ "TabbedPane.focusColor": alpha(ui.primary, 0.5),
+ "TabbedPane.foreground": ui.default,
+
+ "TabbedPane.hoverColor": hoverBg,
+ "TabbedPane.tabSelectionHeight": 3,
+ "TabbedPane.underlineColor": ui.primary,
+ // Table
+ "Table.alternateRowBackground": alpha(ui.uibackgroundalt, 0.5),
+ "Table.background": ui.uibackground,
+ "Table.dropLineColor": ui.primary,
+ "Table.focusCellBackground": selectedBg,
+ "Table.foreground": ui.default,
+ "Table.gridColor": borderColor,
+ "Table.hoverBackground": hoverBg,
+
+ "Table.lightSelectionBackground": alpha(ui.primary, 0.1),
+ "Table.lightSelectionForeground": ui.default,
+
+ "Table.lightSelectionInactiveBackground": alpha(ui.primary, 0.05),
+ "Table.lightSelectionInactiveForeground": ui.default,
+ "Table.selectionBackground": selectedBg,
+ "Table.selectionForeground": ui.default,
+ "Table.selectionInactiveBackground": alpha(ui.primary, 0.1),
+ "Table.selectionInactiveForeground": ui.default,
+ "Table.stripeColor": alpha(ui.uibackgroundalt, 0.5),
+
+ // Tag
+ "Tag.background": alpha(ui.primary, 0.15),
+ "Tag.foreground": ui.primary,
+ // TextArea
+ "TextArea.background": inputBg,
+ "TextArea.caretForeground": ui.primary,
+ "TextArea.foreground": ui.default,
+ "TextArea.inactiveBackground": alpha(inputBg, 0.5),
+ "TextArea.inactiveForeground": ui.defaultalt,
+ "TextArea.selectionBackground": selectedBg,
+ "TextArea.selectionForeground": ui.default,
+ // TextField
+ "TextField.background": inputBg,
+ "TextField.borderColor": borderColor,
+ "TextField.caretForeground": ui.primary,
+ "TextField.disabledBackground": alpha(inputBg, 0.5),
+
+ "TextField.focusedBorderColor": ui.primary,
+ "TextField.foreground": ui.default,
+ "TextField.highlight": selectedBg,
+ "TextField.hoverBorderColor": lightenOrDarken(borderColor, 0.1),
+ "TextField.inactiveBackground": alpha(inputBg, 0.5),
+ "TextField.inactiveForeground": ui.defaultalt,
+ "TextField.placeholderForeground": ui.defaultalt,
+
+ "TextField.selectionBackground": selectedBg,
+ "TextField.selectionForeground": ui.default,
+ // TitlePane
+ "TitlePane.background": ui.uibackgroundalt,
+ "TitlePane.Button.hoverBackground": hoverBg,
+ "TitlePane.foreground": ui.default,
+ "TitlePane.fullScreen.background": ui.uibackgroundalt,
+ "TitlePane.inactiveBackground": ui.uibackgroundalt,
+ "TitlePane.inactiveForeground": ui.defaultalt,
+
+ "TitlePane.infoForeground": ui.defaultalt,
+ // ToggleButton
+ "ToggleButton.background": ui.uibackgroundalt,
+ "ToggleButton.borderColor": borderColor,
+ "ToggleButton.buttonColor": ui.default,
+ "ToggleButton.disabledBorderColor": alpha(borderColor, 0.5),
+
+ "ToggleButton.offBackground": ui.uibackgroundalt,
+ "ToggleButton.offForeground": ui.defaultalt,
+ "ToggleButton.onBackground": ui.primary,
+ "ToggleButton.onForeground": light
+ ? "#FFFFFF"
+ : c(ui.primary).isDark()
+ ? "#FFFFFF"
+ : "#000000",
+ // ToolBar
+ "ToolBar.background": ui.uibackgroundalt,
+ "ToolBar.borderHandleColor": borderColor,
+ "ToolBar.floatingBackground": ui.uibackgroundmid,
+ "ToolBar.foreground": ui.default,
+ "ToolBar.separatorColor": borderColor,
+
+ // ToolTip
+ "ToolTip.Actions.background": ui.uibackgroundalt,
+ "ToolTip.Actions.foreground": ui.default,
+ "ToolTip.Actions.Info.foreground": ui.defaultalt,
+ "ToolTip.background": ui.uibackgroundmid,
+ "ToolTip.borderColor": borderColor,
+ "ToolTip.foreground": ui.default,
+ "ToolTip.infoForeground": ui.defaultalt,
+ "ToolTip.separatorColor": borderColor,
+ "ToolTip.shortcutForeground": ui.defaultalt,
+ // ToolWindow
+ "ToolWindow.background": ui.uibackground,
+ "ToolWindow.Button.hoverBackground": hoverBg,
+ "ToolWindow.Button.selectedBackground": selectedBg,
+ "ToolWindow.Button.selectedForeground": ui.default,
+ "ToolWindow.Header.background": ui.uibackgroundalt,
+ "ToolWindow.Header.borderColor": borderColor,
+ "ToolWindow.Header.closeButton.background": transparent(ui.uibackground),
+ "ToolWindow.Header.inactiveBackground": ui.uibackgroundalt,
+ "ToolWindow.HeaderCloseButton.background": transparent(ui.uibackground),
+ "ToolWindow.HeaderTab.hoverBackground": hoverBg,
+ "ToolWindow.HeaderTab.hoverInactiveBackground": hoverBg,
+ "ToolWindow.HeaderTab.selectedBackground": ui.uibackground,
+
+ "ToolWindow.HeaderTab.selectedInactiveBackground": ui.uibackgroundmid,
+ "ToolWindow.HeaderTab.underlineColor": ui.primary,
+ "ToolWindow.HeaderTab.underlinedTabBackground": ui.uibackground,
+ "ToolWindow.HeaderTab.underlinedTabForeground": ui.default,
+ "ToolWindow.HeaderTab.underlinedTabInactiveBackground": ui.uibackgroundmid,
+ "ToolWindow.HeaderTab.underlinedTabInactiveForeground": ui.defaultalt,
+ "ToolWindow.HeaderTab.underlineHeight": 3,
+
+ "ToolWindow.Stripe.background": ui.uibackgroundalt,
+ "ToolWindow.Stripe.borderColor": transparent(borderColor),
+
+ // Tree
+ "Tree.background": ui.uibackground,
+ "Tree.errorForeground": levels.danger,
+ "Tree.foreground": ui.default,
+ "Tree.hoverBackground": hoverBg,
+ "Tree.modifiedItemForeground": levels.info,
+ "Tree.rowHeight": 24,
+ "Tree.selectionBackground": selectedBg,
+ "Tree.selectionForeground": ui.default,
+ "Tree.selectionInactiveBackground": alpha(ui.primary, 0.1),
+
+ // ValidationTooltip
+ "ValidationTooltip.errorBackground": alpha(levels.danger, 0.15),
+ "ValidationTooltip.errorBorderColor": levels.danger,
+ "ValidationTooltip.warningBackground": alpha(levels.warning, 0.15),
+ "ValidationTooltip.warningBorderColor": levels.warning,
+
+ // VersionControl
+ "VersionControl.FileHistory.Commit.otherBranchBackground":
+ alpha(colors.purple, 0.1),
+ "VersionControl.FileHistory.Commit.selectedBranchBackground":
+ alpha(ui.primary, 0.1),
+ "VersionControl.GitCommits.graphColor": ui.primary,
+ "VersionControl.GitLog.headIconColor": colors.yellow,
+ "VersionControl.GitLog.localBranchIconColor": colors.green,
+ "VersionControl.GitLog.otherIconColor": colors.purple,
+ "VersionControl.GitLog.remoteBranchIconColor": colors.turquoize,
+ "VersionControl.GitLog.tagIconColor": colors.yellow,
+ "VersionControl.HgLog.bookmarkIconColor": colors.green,
+ "VersionControl.HgLog.branchIconColor": colors.turquoize,
+ "VersionControl.HgLog.closedBranchIconColor": alpha(colors.turquoize, 0.5),
+ "VersionControl.HgLog.headIconColor": colors.yellow,
+ "VersionControl.HgLog.localTagIconColor": colors.orange,
+ "VersionControl.HgLog.mqTagIconColor": colors.purple,
+ "VersionControl.HgLog.tagIconColor": colors.yellow,
+ "VersionControl.HgLog.tipIconColor": colors.pink,
+ "VersionControl.Log.Commit.currentBranchBackground": alpha(ui.primary, 0.1),
+ "VersionControl.Log.Commit.hoveredBackground": hoverBg,
+ "VersionControl.Log.Commit.unmatchedForeground": ui.defaultalt,
+ "VersionControl.Ref.background": alpha(ui.primary, 0.15),
+ "VersionControl.Ref.backgroundBase": ui.uibackgroundalt,
+ "VersionControl.RefLabel.background": alpha(ui.primary, 0.15),
+ "VersionControl.RefLabel.backgroundBase": ui.uibackgroundalt,
+ "VersionControl.RefLabel.foreground": ui.default,
+
+ // WelcomeScreen
+ "WelcomeScreen.background": ui.uibackground,
+ "WelcomeScreen.borderColor": borderColor,
+ "WelcomeScreen.captionBackground": ui.uibackgroundalt,
+ "WelcomeScreen.captionForeground": ui.default,
+ "WelcomeScreen.Details.background": ui.uibackgroundalt,
+ "WelcomeScreen.footerBackground": ui.uibackgroundalt,
+ "WelcomeScreen.footerForeground": ui.defaultalt,
+ "WelcomeScreen.groupIconBorderColor": borderColor,
+ "WelcomeScreen.headerBackground": ui.uibackgroundalt,
+ "WelcomeScreen.headerForeground": ui.default,
+ "WelcomeScreen.Projects.actions.background": ui.uibackgroundalt,
+ "WelcomeScreen.Projects.actions.selectionBackground": selectedBg,
+ "WelcomeScreen.Projects.background": ui.uibackground,
+ "WelcomeScreen.Projects.selectionBackground": selectedBg,
+ "WelcomeScreen.Projects.selectionInactiveBackground":
+ alpha(ui.primary, 0.1),
+ "WelcomeScreen.separatorColor": borderColor,
+ "WelcomeScreen.SidePanel.background": ui.uibackgroundalt,
+
+ // Window
+ "window.border": hc ? ui.default : borderColor,
+ };
+}
diff --git a/src/generators/jetbrains/utils.ts b/src/generators/jetbrains/utils.ts
new file mode 100644
index 0000000..a6411b9
--- /dev/null
+++ b/src/generators/jetbrains/utils.ts
@@ -0,0 +1,173 @@
+/**
+ * JetBrains Theme Utility Functions
+ *
+ * Helper functions for color manipulation and formatting
+ * specific to JetBrains theme requirements.
+ */
+
+import { colord as c } from "colord";
+
+/**
+ * Darken a color and return JetBrains-compatible hex
+ *
+ * @param hex - Input color
+ * @param amount - Amount to darken (0-1)
+ * @returns 6-digit hex string without #
+ */
+export function darken(hex: string, amount: number): string {
+ return toHex(c(hex).darken(amount).toHex());
+}
+
+/**
+ * Get a contrasting foreground color (black or white)
+ *
+ * @param background - Background color
+ * @returns "000000" or "FFFFFF"
+ */
+export function getContrastForeground(background: string): string {
+ return isLight(background) ? "000000" : "FFFFFF";
+}
+
+/**
+ * Generate plugin-compatible theme ID
+ *
+ * @param slug - Theme slug
+ * @returns Theme ID for plugin.xml
+ */
+export function getThemeId(slug: string): string {
+ return `bearded-theme-${slug}`;
+}
+
+/**
+ * Generate theme file path for plugin references
+ *
+ * @param slug - Theme slug
+ * @returns Path relative to resources folder
+ */
+export function getThemePath(slug: string): string {
+ return `/themes/bearded-theme-${slug}.theme.json`;
+}
+
+/**
+ * Determine if a color is considered "light"
+ * Useful for deciding contrast colors
+ *
+ * @param hex - Color to check
+ * @returns true if the color is light
+ */
+export function isLight(hex: string): boolean {
+ return c(hex).isLight();
+}
+
+/**
+ * Lighten a color and return JetBrains-compatible hex
+ *
+ * @param hex - Input color
+ * @param amount - Amount to lighten (0-1)
+ * @returns 6-digit hex string without #
+ */
+export function lighten(hex: string, amount: number): string {
+ return toHex(c(hex).lighten(amount).toHex());
+}
+
+/**
+ * Mix two colors and return JetBrains-compatible hex
+ *
+ * @param color1 - First color
+ * @param color2 - Second color
+ * @param ratio - Mix ratio (0 = color1, 1 = color2)
+ * @returns 6-digit hex string without #
+ */
+export function mixColors(
+ color1: string,
+ color2: string,
+ ratio: number = 0.5,
+): string {
+ return toHex(c(color1).mix(color2, ratio).toHex());
+}
+
+/**
+ * Adjust color saturation and return JetBrains-compatible hex
+ *
+ * @param hex - Input color
+ * @param amount - Positive to saturate, negative to desaturate
+ * @returns 6-digit hex string without #
+ */
+export function saturate(hex: string, amount: number): string {
+ if (amount >= 0) {
+ return toHex(c(hex).saturate(amount).toHex());
+ }
+ return toHex(c(hex).desaturate(Math.abs(amount)).toHex());
+}
+
+/**
+ * Escape a theme name to create a valid file slug
+ *
+ * @param name - Theme display name
+ * @returns Sanitized slug for filename
+ */
+export function slugify(name: string): string {
+ return name
+ .toLowerCase()
+ .replace(/\s+/g, "-")
+ .replace(/&/g, "and")
+ .replace(/[^a-z0-9-]/g, "");
+}
+
+/**
+ * Convert a hex color to JetBrains format (6-digit RGB without #)
+ * JetBrains uses RRGGBB format for colors in theme.json
+ *
+ * @param hex - Hex color string (e.g., "#FF5370" or "#FF537080")
+ * @returns 6-digit hex string without # (e.g., "FF5370")
+ */
+export function toHex(hex: string): string {
+ const color = c(hex);
+ // Get RGB hex without alpha
+ return color.toHex().replace("#", "").substring(0, 6).toUpperCase();
+}
+
+/**
+ * Convert a hex color with alpha to JetBrains 8-digit RRGGBBAA format
+ *
+ * @param hex - Hex color string
+ * @param alpha - Alpha value (0-1)
+ * @returns 8-digit hex string without # (e.g., "FF537080")
+ */
+export function toHexAlpha(hex: string, alpha: number): string {
+ const color = c(hex).alpha(alpha);
+ const rgbHex = color.toHex().replace("#", "").toUpperCase();
+
+ // Ensure we have 8 characters (RRGGBBAA)
+ if (rgbHex.length === 6) {
+ const alphaHex = Math.round(alpha * 255)
+ .toString(16)
+ .padStart(2, "0")
+ .toUpperCase();
+ return rgbHex + alphaHex;
+ }
+
+ return rgbHex;
+}
+
+/**
+ * Generate a fully transparent color (for hiding elements)
+ *
+ * @param hex - Base color (only RGB will be used)
+ * @returns 8-digit hex with # prefix and 00 alpha (e.g., "#1C243300")
+ */
+export function transparent(hex: string): string {
+ return "#" + toHex(hex) + "00";
+}
+
+/**
+ * Create a transparent version of a color for JetBrains
+ * Returns full 8-digit RRGGBBAA format
+ *
+ * @param hex - Input color
+ * @param alpha - Alpha value (0-1)
+ * @returns 8-digit hex string without # (e.g., "FF537080")
+ */
+export function withAlpha(hex: string, alpha: number): string {
+ return toHexAlpha(hex, alpha);
+}
diff --git a/src/version-manager.ts b/src/version-manager.ts
index a9fda3c..31b0ea9 100644
--- a/src/version-manager.ts
+++ b/src/version-manager.ts
@@ -5,6 +5,7 @@ import { join } from "path";
* Configuration interface for IDE versions
*/
export interface VersionConfig {
+ jetbrains: string;
vscode: string;
zed: string;
}
@@ -16,6 +17,14 @@ export function getAllVersions(): VersionConfig {
return getVersionConfig();
}
+/**
+ * Get JetBrains version from versions.json
+ */
+export function getJetBrainsVersion(): string {
+ const config = getVersionConfig();
+ return config.jetbrains;
+}
+
/**
* Get version from package.json (for backwards compatibility)
*/
@@ -62,6 +71,7 @@ function getVersionConfig(): VersionConfig {
error,
);
return {
+ jetbrains: "1.0.0",
vscode: "1.0.0",
zed: "1.0.0",
};
diff --git a/versions.json b/versions.json
index b7a55a9..9922f36 100644
--- a/versions.json
+++ b/versions.json
@@ -1,4 +1,5 @@
{
"vscode": "11.0.0",
- "zed": "1.0.0"
+ "zed": "1.0.0",
+ "jetbrains": "1.0.0"
}
From c5c12fcc791860af212e43326e5709db8876ef43 Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Tue, 20 Jan 2026 12:33:49 +0100
Subject: [PATCH 2/9] Pre-mix tag colors and add Vue editor attributes
Pre-mix colors with the UI background to simulate alpha transparency for
JetBrains attributes since they don't support alpha channels
---
src/generators/jetbrains/editor-scheme.ts | 28 ++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/src/generators/jetbrains/editor-scheme.ts b/src/generators/jetbrains/editor-scheme.ts
index af319da..66a9b0d 100644
--- a/src/generators/jetbrains/editor-scheme.ts
+++ b/src/generators/jetbrains/editor-scheme.ts
@@ -61,6 +61,12 @@ function buildAttributeOptions(
): string {
const { colors, ui } = theme;
+ // Helper to mix color with background to simulate transparency
+ // JetBrains attributes don't support alpha, so we pre-mix
+ const mixWithBg = (color: string, alpha: number): string => {
+ return c(color).mix(ui.uibackground, 1 - alpha).toHex();
+ };
+
// Helper to create an attribute option
const attr = (
name: string,
@@ -216,17 +222,37 @@ function buildAttributeOptions(
attr("DEFAULT_ENTITY", { foreground: colors.orange }),
// HTML specific
+ attr("HTML_TAG", {
+ foreground: isHc ? colors.blue : mixWithBg(colors.blue, 0.7),
+ }),
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 }),
+ attr("HTML_CUSTOM_TAG_NAME", { foreground: colors.greenAlt }),
// XML specific
+ attr("XML_TAG", {
+ foreground: isHc ? colors.blue : mixWithBg(colors.blue, 0.7),
+ }),
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 }),
+
+ // Vue.js specific
+ attr("VUE_TAG", {
+ foreground: isHc ? colors.blue : mixWithBg(colors.blue, 0.7),
+ }),
+ attr("VUE_TAG_NAME", { foreground: colors.blue }),
+ attr("VUE_CUSTOM_TAG_NAME", { foreground: colors.greenAlt }),
+ attr("VUE_ATTRIBUTE_NAME", { foreground: colors.yellow }),
+ attr("VUE_ATTRIBUTE_VALUE", { foreground: colors.green }),
+ attr("VUE_DIRECTIVE", { foreground: colors.purple }),
+ attr("VUE_DIRECTIVE_ARGUMENT", { foreground: colors.pink }),
+ attr("VUE_DIRECTIVE_SHORTHAND_ARGUMENT", { foreground: colors.pink }),
+ attr("VUE_INTERPOLATION_DELIMITERS", { foreground: colors.yellow }),
+ attr("VUE_EXPRESSION", { foreground: ui.default }),
attr("XML_TAG_DATA", { foreground: ui.default }),
attr("XML_PROLOGUE", { foreground: ui.defaultalt }),
attr("XML_NS_PREFIX", { foreground: colors.turquoize }),
From 89afcad46be65eacd2c982e9391af2c9ab7dc1b5 Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Tue, 20 Jan 2026 12:38:16 +0100
Subject: [PATCH 3/9] JetBrains: Add Window.border and use borderColor
---
src/generators/jetbrains/types.ts | 1 +
src/generators/jetbrains/ui.ts | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/generators/jetbrains/types.ts b/src/generators/jetbrains/types.ts
index 28a5c46..f20922e 100644
--- a/src/generators/jetbrains/types.ts
+++ b/src/generators/jetbrains/types.ts
@@ -752,6 +752,7 @@ export interface JetBrainsUiColors {
"WelcomeScreen.SidePanel.background"?: string;
// Window
+ "Window.border"?: string;
"window.border"?: string;
}
diff --git a/src/generators/jetbrains/ui.ts b/src/generators/jetbrains/ui.ts
index e56db76..24cc1e3 100644
--- a/src/generators/jetbrains/ui.ts
+++ b/src/generators/jetbrains/ui.ts
@@ -252,7 +252,7 @@ export function buildJetBrainsUiColors(
"InplaceRefactoringPopup.borderColor": ui.primary,
"Island.arc": 20,
"Island.arc.compact": 16,
- "Island.borderColor": ui.uibackground,
+ "Island.borderColor": borderColor,
"Island.borderWidth": 5,
"Island.borderWidth.compact": 4,
"Island.inactiveAlpha": 0.44,
@@ -727,6 +727,7 @@ export function buildJetBrainsUiColors(
"WelcomeScreen.SidePanel.background": ui.uibackgroundalt,
// Window
+ "Window.border": `1,1,1,1,${borderColor.replace("#", "")}`,
"window.border": hc ? ui.default : borderColor,
};
}
From 6284cbb7b44fde6e7cefa6728fd3073f2b2f2be5 Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Tue, 20 Jan 2026 14:12:56 +0100
Subject: [PATCH 4/9] Add JetBrains bookmark UI keys
Remove generated Arc theme files (bearded-theme-arc.theme.json,
bearded-theme-arc.xml, bearded-theme-black-&-ruby.xml)
---
bearded-theme-arc.theme.json | 558 ---------------
bearded-theme-arc.xml | 1046 -----------------------------
bearded-theme-black-&-ruby.xml | 1045 ----------------------------
src/generators/jetbrains/types.ts | 137 +++-
src/generators/jetbrains/ui.ts | 162 +++--
5 files changed, 233 insertions(+), 2715 deletions(-)
delete mode 100644 bearded-theme-arc.theme.json
delete mode 100644 bearded-theme-arc.xml
delete mode 100644 bearded-theme-black-&-ruby.xml
diff --git a/bearded-theme-arc.theme.json b/bearded-theme-arc.theme.json
deleted file mode 100644
index fd96df8..0000000
--- a/bearded-theme-arc.theme.json
+++ /dev/null
@@ -1,558 +0,0 @@
-{
- "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
deleted file mode 100644
index 50246b6..0000000
--- a/bearded-theme-arc.xml
+++ /dev/null
@@ -1,1046 +0,0 @@
-
-
-
- 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
deleted file mode 100644
index a54b2c9..0000000
--- a/bearded-theme-black-&-ruby.xml
+++ /dev/null
@@ -1,1045 +0,0 @@
-
-
-
- Bearded Theme Generator
- JetBrains IDE
- 2024.1
- Bearded Theme Black & Ruby
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/generators/jetbrains/types.ts b/src/generators/jetbrains/types.ts
index f20922e..a81e472 100644
--- a/src/generators/jetbrains/types.ts
+++ b/src/generators/jetbrains/types.ts
@@ -144,18 +144,34 @@ export interface JetBrainsUiColors {
"Banner.warningBackground"?: string;
"Banner.warningBorderColor"?: string;
+ // Bookmark
+ "Bookmark.iconBackground"?: string;
+ "Bookmark.Mnemonic.iconForeground"?: string;
+ "Bookmark.MnemonicAssigned.background"?: string;
+ "Bookmark.MnemonicAssigned.foreground"?: string;
+ "Bookmark.MnemonicAvailable.background"?: string;
+ "Bookmark.MnemonicAvailable.borderColor"?: string;
+ "Bookmark.MnemonicAvailable.foreground"?: string;
+ "Bookmark.MnemonicCurrent.background"?: string;
+ "Bookmark.MnemonicCurrent.foreground"?: string;
+
// Borders
"Borders.color"?: string;
"Borders.ContrastBorderColor"?: string;
// Button
"Button.arc"?: number;
+ "Button.background"?: string;
+ "Button.borderColor"?: string;
+ "Button.default.borderColor"?: string;
"Button.default.endBackground"?: string;
"Button.default.focusColor"?: string;
"Button.default.focusedBorderColor"?: string;
"Button.default.foreground"?: string;
"Button.default.shadowColor"?: string;
"Button.default.startBackground"?: string;
+ "Button.disabledBackground"?: string;
+ "Button.disabledBorderColor"?: string;
"Button.disabledText"?: string;
"Button.endBackground"?: string;
"Button.focusedBorderColor"?: string;
@@ -163,23 +179,44 @@ export interface JetBrainsUiColors {
"Button.shadowColor"?: string;
"Button.startBackground"?: string;
- // Checkbox
+ // CheckBox (JDK Swing component)
+ "CheckBox.background"?: string;
+ // Checkbox (IntelliJ Platform component)
"Checkbox.Background.Default"?: string;
"Checkbox.Background.Disabled"?: string;
"Checkbox.Background.Selected"?: string;
+
"Checkbox.Border.Default"?: string;
"Checkbox.Border.Disabled"?: string;
"Checkbox.Border.Selected"?: string;
+ "CheckBox.disabledText"?: string;
"Checkbox.Focus.Thin.Default"?: string;
"Checkbox.Focus.Thin.Selected"?: string;
"Checkbox.Focus.Wide"?: string;
+ "CheckBox.foreground"?: string;
"Checkbox.Foreground.Disabled"?: string;
"Checkbox.Foreground.Selected"?: string;
+ "CheckBox.select"?: string;
+
+ "Code.Block.backgroundColor"?: string;
+ "Code.Block.borderColor"?: string;
+ "Code.Block.borderRadius"?: number;
+ "Code.Block.borderWidth"?: number;
+ "Code.Block.EditorPane.backgroundColor"?: string;
+ "Code.Block.EditorPane.borderColor"?: string;
+ "Code.Block.foregroundColor"?: string;
+ // Code (inline and block code elements)
+ "Code.Inline.backgroundColor"?: string;
+ "Code.Inline.borderColor"?: string;
+ "Code.Inline.borderRadius"?: number;
+ "Code.Inline.borderWidth"?: number;
+ "Code.Inline.foregroundColor"?: string;
// ComboBox
"ComboBox.ArrowButton.background"?: string;
"ComboBox.ArrowButton.disabledIconColor"?: string;
"ComboBox.ArrowButton.iconColor"?: string;
+
"ComboBox.ArrowButton.nonEditableBackground"?: string;
"ComboBox.background"?: string;
"ComboBox.disabledBackground"?: string;
@@ -189,38 +226,62 @@ export interface JetBrainsUiColors {
"ComboBox.nonEditableBackground"?: string;
"ComboBox.selectionBackground"?: string;
"ComboBox.selectionForeground"?: string;
-
+ // CompletionPopup
+ "CompletionPopup.Advertiser.background"?: string;
+ "CompletionPopup.Advertiser.foreground"?: string;
// CompletionPopup
"CompletionPopup.background"?: string;
+
"CompletionPopup.foreground"?: string;
"CompletionPopup.matchForeground"?: string;
"CompletionPopup.selectionBackground"?: string;
"CompletionPopup.selectionForeground"?: string;
"CompletionPopup.selectionInactiveBackground"?: string;
"CompletionPopup.selectionInfoForeground"?: string;
-
+ // Component (Universal JDK component settings)
+ "Component.arc"?: number;
+ "Component.borderColor"?: string;
+ "Component.disabledBorderColor"?: string;
+ "Component.errorFocusColor"?: string;
+ "Component.focusColor"?: string;
+
+ "Component.focusedBorderColor"?: string;
+ "Component.focusWidth"?: number;
+ "Component.inactiveErrorFocusColor"?: string;
+ "Component.inactiveWarningFocusColor"?: string;
+ "Component.infoForeground"?: string;
+ "Component.warningFocusColor"?: string;
// Counter
"Counter.background"?: string;
"Counter.foreground"?: string;
+ "Debugger.EvaluateExpression.background"?: string;
+ "Debugger.Variables.changedValueForeground"?: string;
// Debugger
"Debugger.Variables.collectingDataForeground"?: string;
+
"Debugger.Variables.errorMessageForeground"?: string;
"Debugger.Variables.evaluatingExpressionForeground"?: string;
"Debugger.Variables.modifyingValueForeground"?: string;
- "Debugger.Variables.type"?: string;
-
+ "Debugger.Variables.typeForeground"?: string;
+ "Debugger.Variables.valueForeground"?: string;
// DefaultTabs (for all tabs except TabbedPane)
"DefaultTabs.background"?: string;
"DefaultTabs.borderColor"?: string;
"DefaultTabs.hoverBackground"?: string;
+
"DefaultTabs.inactiveColoredFileBackground"?: string;
"DefaultTabs.inactiveMaskColor"?: string;
"DefaultTabs.underlineColor"?: string;
"DefaultTabs.underlinedTabBackground"?: string;
"DefaultTabs.underlinedTabForeground"?: string;
"DefaultTabs.underlineHeight"?: number;
+ // DisclosureButton
+ "DisclosureButton.arc"?: number;
+ "DisclosureButton.defaultBackground"?: string;
+ "DisclosureButton.hoverOverlay"?: string;
+ "DisclosureButton.pressedOverlay"?: string;
// DragAndDrop
"DragAndDrop.areaBackground"?: string;
"DragAndDrop.areaBorderColor"?: string;
@@ -233,11 +294,18 @@ export interface JetBrainsUiColors {
// EditorPane
"EditorPane.background"?: string;
+ "EditorPane.caretForeground"?: string;
+ "EditorPane.foreground"?: string;
+ "EditorPane.inactiveBackground"?: string;
+ "EditorPane.inactiveForeground"?: string;
+ "EditorPane.selectionBackground"?: string;
+ "EditorPane.selectionForeground"?: string;
// EditorTabs
"EditorTabs.background"?: string;
"EditorTabs.borderColor"?: string;
"EditorTabs.hoverBackground"?: string;
+
"EditorTabs.inactiveColoredFileBackground"?: string;
"EditorTabs.inactiveMaskColor"?: string;
"EditorTabs.inactiveUnderlineColor"?: string;
@@ -247,89 +315,99 @@ export interface JetBrainsUiColors {
"EditorTabs.underlinedTabBackground"?: string;
"EditorTabs.underlinedTabForeground"?: string;
"EditorTabs.underlineHeight"?: number;
-
// FileColor
"FileColor.Blue"?: string;
"FileColor.Green"?: string;
"FileColor.Orange"?: string;
+
"FileColor.Rose"?: string;
"FileColor.Violet"?: string;
"FileColor.Yellow"?: string;
-
// Focus
"Focus.borderColor"?: string;
"Focus.color"?: string;
-
// Git
"Git.Log.Ref.LocalBranch"?: string;
+
"Git.Log.Ref.Other"?: string;
"Git.Log.Ref.RemoteBranch"?: string;
"Git.Log.Ref.Tag"?: string;
-
// Group
"Group.disabledSeparatorColor"?: string;
"Group.separatorColor"?: string;
-
// GutterTooltip
"GutterTooltip.backgroundColor"?: string;
"GutterTooltip.borderColor"?: string;
"GutterTooltip.lineSeparatorColor"?: string;
+ // IconBadge
+ "IconBadge.errorBackground"?: string;
+ "IconBadge.errorForeground"?: string;
+
+ "IconBadge.infoBackground"?: string;
+ "IconBadge.infoForeground"?: string;
+ "IconBadge.successBackground"?: string;
+ "IconBadge.successForeground"?: string;
+
+ "IconBadge.warningBackground"?: string;
+ "IconBadge.warningForeground"?: string;
+
// InfoPanel
"InfoPanel.background"?: string;
"InfoPanel.foreground"?: string;
-
// InplaceRefactoringPopup
"InplaceRefactoringPopup.borderColor"?: string;
// Islands (for Islands theme support)
"Island.arc"?: number;
"Island.arc.compact"?: number;
+
"Island.borderColor"?: string;
+
"Island.borderWidth"?: number;
"Island.borderWidth.compact"?: number;
"Island.inactiveAlpha"?: number;
Islands?: number;
-
// Label
"Label.background"?: string;
"Label.disabledForeground"?: string;
"Label.errorForeground"?: string;
+
"Label.foreground"?: string;
"Label.infoForeground"?: string;
"Label.selectedDisabledForeground"?: string;
"Label.selectedForeground"?: string;
"Label.successForeground"?: string;
"Label.warningForeground"?: string;
-
// Link
"Link.activeForeground"?: string;
"Link.hoverForeground"?: string;
"Link.pressedForeground"?: string;
+
"Link.secondaryForeground"?: string;
"Link.visitedForeground"?: string;
-
// List
"List.background"?: string;
"List.foreground"?: string;
"List.hoverBackground"?: string;
+
"List.selectionBackground"?: string;
"List.selectionForeground"?: string;
"List.selectionInactiveBackground"?: string;
"List.selectionInactiveForeground"?: string;
-
// MainMenu
"MainMenu.background"?: string;
"MainMenu.borderColor"?: string;
"MainMenu.disabledForeground"?: string;
+
"MainMenu.foreground"?: string;
"MainMenu.selectionBackground"?: string;
"MainMenu.selectionForeground"?: string;
-
// MainToolbar
"MainToolbar.background"?: string;
"MainToolbar.borderColor"?: string;
"MainToolbar.Dropdown.background"?: string;
+
"MainToolbar.Dropdown.hoverBackground"?: string;
"MainToolbar.Icon.hoverBackground"?: string;
"MainToolbar.Icon.pressedBackground"?: string;
@@ -343,42 +421,42 @@ export interface JetBrainsUiColors {
"MainWindow.Tab.selectedBackground"?: string;
"MainWindow.Tab.underlineColor"?: string;
"MainWindow.Tab.underlineHeight"?: number;
-
// MemoryIndicator
"MemoryIndicator.allocatedBackground"?: string;
"MemoryIndicator.usedBackground"?: string;
-
// Menu
"Menu.acceleratorForeground"?: string;
+
"Menu.acceleratorSelectionForeground"?: string;
"Menu.background"?: string;
+
"Menu.borderColor"?: string;
"Menu.disabledForeground"?: string;
"Menu.foreground"?: string;
"Menu.selectionBackground"?: string;
"Menu.selectionForeground"?: string;
"Menu.separatorColor"?: string;
-
// MenuItem
"MenuItem.acceleratorForeground"?: string;
"MenuItem.acceleratorSelectionForeground"?: string;
"MenuItem.background"?: string;
+
"MenuItem.disabledForeground"?: string;
"MenuItem.foreground"?: string;
"MenuItem.selectionBackground"?: string;
"MenuItem.selectionForeground"?: string;
-
// NavBar
"NavBar.background"?: string;
"NavBar.borderColor"?: string;
-
// NewUI (for new UI components)
"NewUI.activeBackground"?: string;
// NotificationError
"Notification.background"?: string;
"Notification.borderColor"?: string;
+
"Notification.errorBackground"?: string;
+
"Notification.errorBorderColor"?: string;
"Notification.errorForeground"?: string;
"Notification.foreground"?: string;
@@ -391,23 +469,23 @@ export interface JetBrainsUiColors {
"Notification.ToolWindow.informativeBorderColor"?: string;
"Notification.ToolWindow.warningBackground"?: string;
"Notification.ToolWindow.warningBorderColor"?: string;
-
// Panel
"Panel.background"?: string;
"Panel.foreground"?: string;
-
// ParameterInfo
"ParameterInfo.background"?: string;
+
"ParameterInfo.borderColor"?: string;
"ParameterInfo.currentOverloadBackground"?: string;
+
"ParameterInfo.currentParameterForeground"?: string;
"ParameterInfo.disabledForeground"?: string;
"ParameterInfo.foreground"?: string;
-
// Plugins
"Plugins.Button.installBackground"?: string;
"Plugins.Button.installBorderColor"?: string;
"Plugins.Button.installFillBackground"?: string;
+
"Plugins.Button.installFillForeground"?: string;
"Plugins.Button.installFocusedBackground"?: string;
"Plugins.Button.installForeground"?: string;
@@ -432,11 +510,11 @@ export interface JetBrainsUiColors {
"Plugins.tagForeground"?: string;
"Plugins.trialTagBackground"?: string;
"Plugins.trialTagForeground"?: string;
-
// Popup
"Popup.Advertiser.background"?: string;
"Popup.Advertiser.borderColor"?: string;
"Popup.Advertiser.borderInsets"?: string;
+
"Popup.Advertiser.foreground"?: string;
"Popup.background"?: string;
"Popup.borderColor"?: string;
@@ -446,18 +524,18 @@ export interface JetBrainsUiColors {
"Popup.Separator.foreground"?: string;
"Popup.Toolbar.background"?: string;
"Popup.Toolbar.borderColor"?: string;
-
// PopupMenu
"PopupMenu.background"?: string;
"PopupMenu.foreground"?: string;
"PopupMenu.selectionBackground"?: string;
+
"PopupMenu.selectionForeground"?: string;
"PopupMenu.translucentBackground"?: string;
-
// ProgressBar
"ProgressBar.backgroundColor"?: string;
"ProgressBar.failedColor"?: string;
"ProgressBar.failedEndColor"?: string;
+
"ProgressBar.foreground"?: string;
"ProgressBar.indeterminateEndColor"?: string;
"ProgressBar.indeterminateStartColor"?: string;
@@ -467,6 +545,10 @@ export interface JetBrainsUiColors {
"ProgressBar.selectionBackground"?: string;
"ProgressBar.selectionForeground"?: string;
"ProgressBar.trackColor"?: string;
+ // RadioButton (JDK Swing component)
+ "RadioButton.background"?: string;
+ "RadioButton.disabledText"?: string;
+ "RadioButton.foreground"?: string;
// RunWidget
"RunWidget.background"?: string;
@@ -752,7 +834,6 @@ export interface JetBrainsUiColors {
"WelcomeScreen.SidePanel.background"?: string;
// Window
- "Window.border"?: string;
"window.border"?: string;
}
diff --git a/src/generators/jetbrains/ui.ts b/src/generators/jetbrains/ui.ts
index 24cc1e3..d69640c 100644
--- a/src/generators/jetbrains/ui.ts
+++ b/src/generators/jetbrains/ui.ts
@@ -95,6 +95,25 @@ export function buildJetBrainsUiColors(
"Banner.warningBackground": alpha(levels.warning, 0.15),
"Banner.warningBorderColor": alpha(levels.warning, 0.5),
+ // Bookmark
+ "Bookmark.iconBackground": ui.primary,
+ "Bookmark.Mnemonic.iconForeground": light
+ ? "#FFFFFF"
+ : c(ui.primary).isDark()
+ ? "#FFFFFF"
+ : "#000000",
+ "Bookmark.MnemonicAssigned.background": alpha(ui.primary, 0.15),
+ "Bookmark.MnemonicAssigned.foreground": ui.default,
+ "Bookmark.MnemonicAvailable.background": ui.uibackgroundalt,
+ "Bookmark.MnemonicAvailable.borderColor": borderColor,
+ "Bookmark.MnemonicAvailable.foreground": ui.defaultalt,
+ "Bookmark.MnemonicCurrent.background": ui.primary,
+ "Bookmark.MnemonicCurrent.foreground": light
+ ? "#FFFFFF"
+ : c(ui.primary).isDark()
+ ? "#FFFFFF"
+ : "#000000",
+
// Borders
"Borders.color": borderColor,
"Borders.ContrastBorderColor": hc
@@ -103,16 +122,17 @@ export function buildJetBrainsUiColors(
// Button
"Button.arc": 6,
- "Button.default.endBackground": ui.primary,
+ "Button.background": ui.uibackgroundalt,
+ "Button.borderColor": borderColor,
+ "Button.default.borderColor": transparent(borderColor),
+ "Button.default.endBackground": alpha(ui.primary, 0.25),
"Button.default.focusColor": alpha(ui.primary, 0.5),
- "Button.default.focusedBorderColor": c(ui.primary).lighten(0.2).toHex(),
- "Button.default.foreground": light
- ? "#FFFFFF"
- : c(ui.primary).isDark()
- ? "#FFFFFF"
- : "#000000",
+ "Button.default.focusedBorderColor": alpha(ui.primary, 0.5),
+ "Button.default.foreground": ui.default,
"Button.default.shadowColor": transparent(ui.uibackground),
- "Button.default.startBackground": ui.primary,
+ "Button.default.startBackground": alpha(ui.primary, 0.25),
+ "Button.disabledBackground": alpha(ui.uibackgroundalt, 0.5),
+ "Button.disabledBorderColor": alpha(borderColor, 0.5),
"Button.disabledText": alpha(ui.default, 0.4),
"Button.endBackground": ui.uibackgroundalt,
"Button.focusedBorderColor": ui.primary,
@@ -120,46 +140,86 @@ export function buildJetBrainsUiColors(
"Button.shadowColor": transparent(ui.uibackground),
"Button.startBackground": ui.uibackgroundalt,
- // Checkbox
+ // CheckBox (JDK Swing component)
+ "CheckBox.background": ui.uibackground,
+ // Checkbox (IntelliJ Platform component)
"Checkbox.Background.Default": inputBg,
"Checkbox.Background.Disabled": alpha(inputBg, 0.5),
"Checkbox.Background.Selected": ui.primary,
+
"Checkbox.Border.Default": borderColor,
"Checkbox.Border.Disabled": alpha(borderColor, 0.5),
"Checkbox.Border.Selected": ui.primary,
+ "CheckBox.disabledText": alpha(ui.default, 0.4),
"Checkbox.Focus.Thin.Default": alpha(ui.primary, 0.5),
"Checkbox.Focus.Thin.Selected": alpha(ui.primary, 0.5),
"Checkbox.Focus.Wide": alpha(ui.primary, 0.3),
+ "CheckBox.foreground": ui.default,
"Checkbox.Foreground.Disabled": alpha(ui.default, 0.4),
"Checkbox.Foreground.Selected": light
? "#FFFFFF"
: c(ui.primary).isDark()
? "#FFFFFF"
: "#000000",
-
+ "CheckBox.select": ui.primary,
+
+ // Code (inline and block code elements)
+ "Code.Block.backgroundColor": alpha(ui.uibackgroundalt, 0.5),
+ "Code.Block.borderColor": borderColor,
+ "Code.Block.borderRadius": 4,
+
+ "Code.Block.borderWidth": 1,
+ "Code.Block.EditorPane.backgroundColor": alpha(ui.uibackgroundalt, 0.3),
+ "Code.Block.EditorPane.borderColor": alpha(borderColor, 0.5),
+ "Code.Block.foregroundColor": ui.default,
+ "Code.Inline.backgroundColor": alpha(colors.orange, 0.15),
+ "Code.Inline.borderColor": alpha(colors.orange, 0.3),
+ "Code.Inline.borderRadius": 3,
+ "Code.Inline.borderWidth": 1,
+ "Code.Inline.foregroundColor": colors.orange,
// ComboBox
"ComboBox.ArrowButton.background": inputBg,
"ComboBox.ArrowButton.disabledIconColor": alpha(ui.default, 0.3),
"ComboBox.ArrowButton.iconColor": ui.defaultalt,
+
"ComboBox.ArrowButton.nonEditableBackground": inputBg,
"ComboBox.background": inputBg,
"ComboBox.disabledBackground": alpha(inputBg, 0.5),
"ComboBox.disabledForeground": alpha(ui.default, 0.4),
"ComboBox.foreground": ui.default,
"ComboBox.modifiedItemForeground": levels.info,
+
"ComboBox.nonEditableBackground": inputBg,
"ComboBox.selectionBackground": selectedBg,
"ComboBox.selectionForeground": ui.default,
+ // CompletionPopup
+ "CompletionPopup.Advertiser.background": ui.uibackgroundalt,
+ "CompletionPopup.Advertiser.foreground": ui.defaultalt,
// CompletionPopup
"CompletionPopup.background": ui.uibackgroundmid,
+
"CompletionPopup.foreground": ui.default,
"CompletionPopup.matchForeground": ui.primary,
"CompletionPopup.selectionBackground": selectedBg,
"CompletionPopup.selectionForeground": ui.default,
"CompletionPopup.selectionInactiveBackground": alpha(ui.primary, 0.1),
"CompletionPopup.selectionInfoForeground": ui.defaultalt,
-
+ // Component (Universal JDK component settings)
+ "Component.arc": 6,
+ // Component (Universal JDK component settings)
+ "Component.borderColor": borderColor,
+ "Component.disabledBorderColor": alpha(borderColor, 0.5),
+
+ "Component.errorFocusColor": alpha(levels.danger, 0.5),
+ "Component.focusColor": alpha(ui.primary, 0.5),
+ "Component.focusedBorderColor": ui.primary,
+ "Component.focusWidth": 2,
+ "Component.inactiveErrorFocusColor": alpha(levels.danger, 0.3),
+
+ "Component.inactiveWarningFocusColor": alpha(levels.warning, 0.3),
+ "Component.infoForeground": ui.defaultalt,
+ "Component.warningFocusColor": alpha(levels.warning, 0.5),
// Counter
"Counter.background": ui.primary,
"Counter.foreground": light
@@ -167,25 +227,34 @@ export function buildJetBrainsUiColors(
: c(ui.primary).isDark()
? "#FFFFFF"
: "#000000",
+ "Debugger.EvaluateExpression.background": inputBg,
+ "Debugger.Variables.changedValueForeground": colors.yellow,
// Debugger
"Debugger.Variables.collectingDataForeground": ui.defaultalt,
+
"Debugger.Variables.errorMessageForeground": levels.danger,
"Debugger.Variables.evaluatingExpressionForeground": levels.info,
"Debugger.Variables.modifyingValueForeground": levels.warning,
- "Debugger.Variables.type": colors.purple,
-
+ "Debugger.Variables.typeForeground": colors.purple,
+ "Debugger.Variables.valueForeground": ui.default,
// DefaultTabs
"DefaultTabs.background": ui.uibackgroundalt,
"DefaultTabs.borderColor": borderColor,
"DefaultTabs.hoverBackground": hoverBg,
+
"DefaultTabs.inactiveColoredFileBackground": transparent(ui.uibackground),
"DefaultTabs.inactiveMaskColor": transparent(ui.uibackground),
"DefaultTabs.underlineColor": ui.primary,
"DefaultTabs.underlinedTabBackground": ui.uibackground,
"DefaultTabs.underlinedTabForeground": ui.default,
"DefaultTabs.underlineHeight": 3,
+ // DisclosureButton
+ "DisclosureButton.arc": 6,
+ "DisclosureButton.defaultBackground": ui.uibackgroundalt,
+ "DisclosureButton.hoverOverlay": alpha(ui.primary, 0.1),
+ "DisclosureButton.pressedOverlay": alpha(ui.primary, 0.2),
// DragAndDrop
"DragAndDrop.areaBackground": alpha(ui.primary, 0.1),
"DragAndDrop.areaBorderColor": ui.primary,
@@ -198,59 +267,73 @@ export function buildJetBrainsUiColors(
// EditorPane
"EditorPane.background": ui.uibackground,
+ "EditorPane.caretForeground": ui.primary,
+ "EditorPane.foreground": ui.default,
+ "EditorPane.inactiveBackground": alpha(ui.uibackground, 0.5),
+ "EditorPane.inactiveForeground": ui.defaultalt,
+ "EditorPane.selectionBackground": selectedBg,
+ "EditorPane.selectionForeground": ui.default,
// EditorTabs
"EditorTabs.background": ui.uibackgroundalt,
"EditorTabs.borderColor": borderColor,
"EditorTabs.hoverBackground": hoverBg,
+
"EditorTabs.inactiveColoredFileBackground": transparent(ui.uibackground),
"EditorTabs.inactiveMaskColor": transparent(ui.uibackground),
"EditorTabs.inactiveUnderlineColor": alpha(ui.primary, 0.5),
"EditorTabs.inactiveUnderlinedTabBackground": ui.uibackgroundmid,
- "EditorTabs.inactiveUnderlinedTabBorderColor": alpha(ui.primary, 0.5),
"EditorTabs.underlineArc": 0,
"EditorTabs.underlineColor": ui.primary,
// Islands-specific tab colors
- "EditorTabs.underlinedBorderColor": ui.primary,
"EditorTabs.underlinedTabBackground": ui.uibackground,
-
"EditorTabs.underlinedTabForeground": ui.default,
"EditorTabs.underlineHeight": 3,
// FileColor
"FileColor.Blue": alpha(colors.blue, 0.15),
+
"FileColor.Green": alpha(colors.green, 0.15),
"FileColor.Orange": alpha(colors.orange, 0.15),
"FileColor.Rose": alpha(colors.pink, 0.15),
-
"FileColor.Violet": alpha(colors.purple, 0.15),
"FileColor.Yellow": alpha(colors.yellow, 0.15),
-
// Focus
"Focus.borderColor": ui.primary,
"Focus.color": alpha(ui.primary, 0.5),
// Git
"Git.Log.Ref.LocalBranch": colors.green,
- "Git.Log.Ref.Other": colors.purple,
+ "Git.Log.Ref.Other": colors.purple,
"Git.Log.Ref.RemoteBranch": colors.turquoize,
"Git.Log.Ref.Tag": colors.yellow,
-
// Group
"Group.disabledSeparatorColor": alpha(borderColor, 0.5),
"Group.separatorColor": borderColor,
// GutterTooltip
"GutterTooltip.backgroundColor": ui.uibackgroundmid,
-
"GutterTooltip.borderColor": borderColor,
"GutterTooltip.lineSeparatorColor": borderColor,
+ // IconBadge
+ "IconBadge.errorBackground": levels.danger,
+ "IconBadge.errorForeground": "#FFFFFF",
+ "IconBadge.infoBackground": levels.info,
+ "IconBadge.infoForeground": "#FFFFFF",
+
+ "IconBadge.successBackground": levels.success,
+ "IconBadge.successForeground": "#FFFFFF",
+
+ "IconBadge.warningBackground": levels.warning,
+ "IconBadge.warningForeground": "#FFFFFF",
// InfoPanel
"InfoPanel.background": ui.uibackgroundalt,
"InfoPanel.foreground": ui.default,
// InplaceRefactoringPopup
"InplaceRefactoringPopup.borderColor": ui.primary,
+
"Island.arc": 20,
+
"Island.arc.compact": 16,
"Island.borderColor": borderColor,
"Island.borderWidth": 5,
@@ -259,34 +342,34 @@ export function buildJetBrainsUiColors(
// Islands Theme Support
// See: https://plugins.jetbrains.com/docs/intellij/supporting-islands-theme.html
Islands: 1,
-
// Label
"Label.background": ui.uibackground,
"Label.disabledForeground": alpha(ui.default, 0.4),
"Label.errorForeground": levels.danger,
+
"Label.foreground": ui.default,
"Label.infoForeground": levels.info,
-
"Label.selectedDisabledForeground": alpha(ui.default, 0.4),
"Label.selectedForeground": ui.default,
"Label.successForeground": levels.success,
+
"Label.warningForeground": levels.warning,
// Link
"Link.activeForeground": c(ui.primary).lighten(0.1).toHex(),
"Link.hoverForeground": c(ui.primary).lighten(0.1).toHex(),
"Link.pressedForeground": c(ui.primary).darken(0.1).toHex(),
-
"Link.secondaryForeground": ui.defaultalt,
"Link.visitedForeground": colors.purple,
// List
"List.background": ui.uibackground,
+
"List.foreground": ui.default,
"List.hoverBackground": hoverBg,
"List.selectionBackground": selectedBg,
-
"List.selectionForeground": ui.default,
"List.selectionInactiveBackground": alpha(ui.primary, 0.1),
"List.selectionInactiveForeground": ui.default,
+
// MainMenu
"MainMenu.background": ui.uibackgroundalt,
"MainMenu.borderColor": borderColor,
@@ -302,13 +385,13 @@ export function buildJetBrainsUiColors(
"MainToolbar.Icon.hoverBackground": hoverBg,
"MainToolbar.Icon.pressedBackground": activeBg,
"MainToolbar.inactiveBackground": ui.uibackgroundalt,
-
"MainToolbar.separatorColor": borderColor,
"MainWindow.background": lightenOrDarken(ui.uibackgroundalt, 0.05),
-
"MainWindow.Tab.background": ui.uibackgroundalt,
+
"MainWindow.Tab.foreground": ui.defaultalt,
"MainWindow.Tab.hoverBackground": hoverBg,
+
"MainWindow.Tab.inactiveUnderlineColor": alpha(ui.primary, 0.5),
"MainWindow.Tab.selectedBackground": ui.uibackground,
"MainWindow.Tab.underlineColor": ui.primary,
@@ -316,23 +399,23 @@ export function buildJetBrainsUiColors(
// MemoryIndicator
"MemoryIndicator.allocatedBackground": alpha(ui.primary, 0.2),
"MemoryIndicator.usedBackground": ui.primary,
-
// Menu
"Menu.acceleratorForeground": ui.defaultalt,
"Menu.acceleratorSelectionForeground": ui.default,
"Menu.background": ui.uibackgroundmid,
+
"Menu.borderColor": borderColor,
"Menu.disabledForeground": alpha(ui.default, 0.4),
"Menu.foreground": ui.default,
"Menu.selectionBackground": selectedBg,
-
"Menu.selectionForeground": ui.default,
"Menu.separatorColor": borderColor,
-
// MenuItem
"MenuItem.acceleratorForeground": ui.defaultalt,
+
"MenuItem.acceleratorSelectionForeground": ui.default,
"MenuItem.background": ui.uibackgroundmid,
+
"MenuItem.disabledForeground": alpha(ui.default, 0.4),
"MenuItem.foreground": ui.default,
"MenuItem.selectionBackground": selectedBg,
@@ -347,21 +430,21 @@ export function buildJetBrainsUiColors(
"Notification.errorBorderColor": levels.danger,
"Notification.errorForeground": ui.default,
"Notification.foreground": ui.default,
-
"Notification.linkForeground": ui.primary,
"Notification.MoreButton.background": ui.uibackgroundalt,
-
"Notification.MoreButton.foreground": ui.default,
+
"Notification.ToolWindow.errorBackground": alpha(levels.danger, 0.15),
"Notification.ToolWindow.errorBorderColor": levels.danger,
+
"Notification.ToolWindow.informativeBackground": alpha(levels.info, 0.15),
"Notification.ToolWindow.informativeBorderColor": levels.info,
"Notification.ToolWindow.warningBackground": alpha(levels.warning, 0.15),
-
"Notification.ToolWindow.warningBorderColor": levels.warning,
// Panel
"Panel.background": ui.uibackground,
"Panel.foreground": ui.default,
+
// ParameterInfo
"ParameterInfo.background": ui.uibackgroundmid,
"ParameterInfo.borderColor": borderColor,
@@ -388,10 +471,10 @@ export function buildJetBrainsUiColors(
"Plugins.paidTagForeground": colors.green,
"Plugins.SearchField.background": inputBg,
"Plugins.SearchField.borderColor": borderColor,
-
"Plugins.SectionHeader.background": ui.uibackgroundalt,
"Plugins.SectionHeader.foreground": ui.default,
"Plugins.Tab.hoverBackground": hoverBg,
+
"Plugins.Tab.selectedBackground": selectedBg,
"Plugins.Tab.selectedForeground": ui.default,
"Plugins.tagBackground": alpha(ui.primary, 0.15),
@@ -402,16 +485,16 @@ export function buildJetBrainsUiColors(
"Popup.Advertiser.background": ui.uibackgroundalt,
"Popup.Advertiser.borderColor": borderColor,
"Popup.Advertiser.borderInsets": "1,1,1,1",
-
"Popup.Advertiser.foreground": ui.defaultalt,
"Popup.background": ui.uibackgroundmid,
"Popup.borderColor": borderColor,
+
"Popup.Header.activeBackground": ui.uibackgroundalt,
"Popup.Header.inactiveBackground": ui.uibackgroundalt,
-
"Popup.inactiveBorderColor": alpha(borderColor, 0.5),
"Popup.Separator.foreground": borderColor,
"Popup.Toolbar.background": ui.uibackgroundalt,
+
"Popup.Toolbar.borderColor": borderColor,
// PopupMenu
"PopupMenu.background": ui.uibackgroundmid,
@@ -423,16 +506,20 @@ export function buildJetBrainsUiColors(
"ProgressBar.backgroundColor": ui.uibackgroundalt,
"ProgressBar.failedColor": levels.danger,
"ProgressBar.failedEndColor": c(levels.danger).lighten(0.1).toHex(),
-
"ProgressBar.foreground": ui.primary,
"ProgressBar.indeterminateEndColor": c(ui.primary).lighten(0.15).toHex(),
"ProgressBar.indeterminateStartColor": ui.primary,
+
"ProgressBar.passedColor": levels.success,
"ProgressBar.passedEndColor": c(levels.success).lighten(0.1).toHex(),
"ProgressBar.progressColor": ui.primary,
"ProgressBar.selectionBackground": ui.uibackgroundalt,
"ProgressBar.selectionForeground": ui.default,
"ProgressBar.trackColor": ui.uibackgroundalt,
+ // RadioButton (JDK Swing component)
+ "RadioButton.background": ui.uibackground,
+ "RadioButton.disabledText": alpha(ui.default, 0.4),
+ "RadioButton.foreground": ui.default,
// RunWidget
"RunWidget.background": ui.uibackgroundalt,
"RunWidget.foreground": ui.default,
@@ -727,7 +814,6 @@ export function buildJetBrainsUiColors(
"WelcomeScreen.SidePanel.background": ui.uibackgroundalt,
// Window
- "Window.border": `1,1,1,1,${borderColor.replace("#", "")}`,
"window.border": hc ? ui.default : borderColor,
};
}
From 53ec9c2ed362a4fb1017e98ebe8eece453586eb8 Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Tue, 20 Jan 2026 14:13:06 +0100
Subject: [PATCH 5/9] Add .claude to .gitignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index cbec71b..59b4442 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ node_modules
*.zip
.env
dist
+.claude/
From c5ed24c9a58b5ace5c4abc7ef8cf428480617ab8 Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Wed, 21 Jan 2026 22:53:07 +0100
Subject: [PATCH 6/9] Revamp release workflow and add JetBrains
Modularize publish.sh into IDE-specific publish functions and require
an IDE argument. Update package.json scripts (per-IDE release/publish
commands, build output paths) and add release:{vscode,zed,jetbrains}
helpers. Remove legacy publish.bat and tidy obsolete single-folder
release notes. Update bump-version and create-release-notes to read
versions.json and emit per-IDE release files. Add commit/release
convention and workflow docs to AGENTS.md
---
AGENTS.md | 93 ++++++++++-
VERSIONING.md | 129 +++++++++++++--
package.json | 20 +--
publish.bat | 114 -------------
publish.sh | 276 +++++++++++++++++++++++---------
releases/jetbrains/.gitkeep | 0
releases/{ => vscode}/10.0.0.md | 0
releases/{ => vscode}/10.1.0.md | 0
releases/{ => vscode}/8.3.2.md | 0
releases/{ => vscode}/9.0.0.md | 0
releases/{ => vscode}/9.0.1.md | 0
releases/{ => vscode}/9.1.0.md | 0
releases/{ => vscode}/9.1.1.md | 0
releases/{ => vscode}/9.1.2.md | 0
releases/{ => vscode}/9.1.3.md | 0
releases/{ => vscode}/9.1.4.md | 0
releases/{ => vscode}/9.1.5.md | 0
releases/{ => vscode}/9.2.0.md | 0
releases/{ => vscode}/9.3.0.md | 0
releases/zed/.gitkeep | 0
src/bump-version.ts | 58 +++++--
src/create-release-notes.ts | 144 ++++++++++++++---
22 files changed, 578 insertions(+), 256 deletions(-)
delete mode 100644 publish.bat
create mode 100644 releases/jetbrains/.gitkeep
rename releases/{ => vscode}/10.0.0.md (100%)
rename releases/{ => vscode}/10.1.0.md (100%)
rename releases/{ => vscode}/8.3.2.md (100%)
rename releases/{ => vscode}/9.0.0.md (100%)
rename releases/{ => vscode}/9.0.1.md (100%)
rename releases/{ => vscode}/9.1.0.md (100%)
rename releases/{ => vscode}/9.1.1.md (100%)
rename releases/{ => vscode}/9.1.2.md (100%)
rename releases/{ => vscode}/9.1.3.md (100%)
rename releases/{ => vscode}/9.1.4.md (100%)
rename releases/{ => vscode}/9.1.5.md (100%)
rename releases/{ => vscode}/9.2.0.md (100%)
rename releases/{ => vscode}/9.3.0.md (100%)
create mode 100644 releases/zed/.gitkeep
diff --git a/AGENTS.md b/AGENTS.md
index 0fd4569..a52aea3 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -437,11 +437,94 @@ When creating or modifying themes:
## Version and Release
-1. Update version in `package.json`
-2. Create release notes: `npm run create:release-notes`
-3. Edit `releases/{version}.md` with changes
-4. Build extension: `npm run build:ext:vscode`
-5. Publish: `npm run publish:all`
+Each IDE is versioned and released independently. Versions are stored in `versions.json`.
+
+### Commit Convention
+
+Use IDE prefixes to target specific platforms in changelogs:
+
+```bash
+# VS Code specific
+[vscode] feat: add new color token
+[vscode] fix: correct bracket highlighting
+
+# Zed specific
+[zed] feat: add panel styling
+[zed] fix: correct status bar colors
+
+# JetBrains specific
+[jetbrains] feat: add bookmark UI support
+[jetbrains] fix: correct editor gutter colors
+
+# Global changes (included in ALL IDEs)
+feat: update syntax colors
+fix: improve contrast ratios
+```
+
+### Commit Types
+
+- `feat:` / `add:` - New features
+- `fix:` / `bug:` - Bug fixes
+- `improve:` / `enhancement:` - Improvements
+- `chore:` - Maintenance tasks
+- `docs:` - Documentation
+- `refactor:` - Code refactoring
+
+### Release Workflow
+
+**For VS Code:**
+
+```bash
+npm run bump:version vscode minor
+npm run build:vscode
+npm run create:release-notes vscode
+# Edit releases/vscode/{version}.md
+npm run build:ext:vscode
+./publish.sh vscode
+```
+
+**For Zed:**
+
+```bash
+npm run bump:version zed patch
+npm run build:zed
+npm run create:release-notes zed
+# Edit releases/zed/{version}.md
+# Commit and push, then open PR to zed-industries/extensions
+./publish.sh zed
+```
+
+**For JetBrains:**
+
+```bash
+npm run bump:version jetbrains patch
+npm run build:jetbrains
+npm run create:release-notes jetbrains
+# Edit releases/jetbrains/{version}.md
+npm run build:ext:jetbrains
+./publish.sh jetbrains
+```
+
+### Git Tags
+
+Each IDE has its own tag format:
+
+- VS Code: `vscode-v11.0.1`
+- Zed: `zed-v1.0.1`
+- JetBrains: `jetbrains-v1.0.1`
+
+### Release Notes Structure
+
+```
+releases/
+├── vscode/
+│ ├── 11.0.0.md
+│ └── 11.0.0.vsix
+├── zed/
+│ └── 1.0.0.md
+└── jetbrains/
+ └── 1.0.0.md
+```
## Dependencies
diff --git a/VERSIONING.md b/VERSIONING.md
index b98df9a..17da365 100644
--- a/VERSIONING.md
+++ b/VERSIONING.md
@@ -6,6 +6,7 @@ Bearded Theme uses **independent versions** for each IDE:
- **VS Code**: Version **11.0.0** (continues historical numbering)
- **Zed**: Version **1.0.0** (fresh start)
+- **JetBrains**: Version **1.0.0** (fresh start)
## Configuration
@@ -14,7 +15,8 @@ All versions are stored in `versions.json`:
```json
{
"vscode": "11.0.0",
- "zed": "1.0.0"
+ "zed": "1.0.0",
+ "jetbrains": "1.0.0"
}
```
@@ -29,13 +31,16 @@ cat versions.json
### Update versions
```bash
+# Bump VS Code: 11.0.0 → 11.1.0
+npm run bump:version vscode minor
+
# Bump Zed: 1.0.0 → 1.0.1
npm run bump:version zed patch
-# Bump VS Code: 11.0.0 → 11.1.0
-npm run bump:version vscode minor
+# Bump JetBrains: 1.0.0 → 1.0.1
+npm run bump:version jetbrains patch
-# Bump both
+# Bump all IDEs
npm run bump:version all patch
```
@@ -45,39 +50,134 @@ npm run bump:version all patch
- `minor` - New features (1.0.0 → 1.1.0)
- `major` - Breaking changes (1.0.0 → 2.0.0)
+## Release Notes
+
+Each IDE has its own release notes folder:
+
+```
+releases/
+├── vscode/
+│ ├── 11.0.0.md
+│ └── 11.0.0.vsix
+├── zed/
+│ └── 1.0.0.md
+└── jetbrains/
+ └── 1.0.0.md
+```
+
+### Create release notes
+
+```bash
+npm run create:release-notes vscode
+npm run create:release-notes zed
+npm run create:release-notes jetbrains
+```
+
+## Commit Convention
+
+Use IDE prefixes to target specific platforms in release notes:
+
+```bash
+# VS Code specific
+[vscode] feat: add new color token
+[vscode] fix: correct bracket highlighting
+
+# Zed specific
+[zed] feat: add panel styling
+[zed] fix: correct status bar colors
+
+# JetBrains specific
+[jetbrains] feat: add bookmark UI support
+[jetbrains] fix: correct editor gutter colors
+
+# Global (included in ALL IDEs)
+feat: update syntax colors
+fix: improve contrast ratios
+```
+
+### Commit types
+
+- `feat:` / `add:` - New features
+- `fix:` / `bug:` - Bug fixes
+- `improve:` / `enhancement:` - Improvements
+- `chore:` - Maintenance tasks
+- `docs:` - Documentation
+- `refactor:` - Code refactoring
+
## Workflows
+### For VS Code
+
+```bash
+npm run bump:version vscode minor
+npm run build:vscode
+npm run create:release-notes vscode
+# Edit releases/vscode/{version}.md
+npm run build:ext:vscode
+./publish.sh vscode
+```
+
### For Zed
```bash
npm run bump:version zed patch
npm run build:zed
-# Version appears in dist/zed/extension.toml
+npm run create:release-notes zed
+# Edit releases/zed/{version}.md
+# Commit and push changes
+# Open PR to zed-industries/extensions
+./publish.sh zed
```
-### For VS Code
+### For JetBrains
```bash
-npm run bump:version vscode minor
-npm run build:vscode
-npm run create:release-notes
-# Version synced to both versions.json and package.json
+npm run bump:version jetbrains patch
+npm run build:jetbrains
+npm run create:release-notes jetbrains
+# Edit releases/jetbrains/{version}.md
+npm run build:ext:jetbrains
+./publish.sh jetbrains
+```
+
+## Git Tags
+
+Each IDE has its own tag format:
+
+- VS Code: `vscode-v11.0.1`
+- Zed: `zed-v1.0.1`
+- JetBrains: `jetbrains-v1.0.1`
+
+Tags are created via the `publish.bat` script or manually:
+
+```bash
+npm run release:vscode
+npm run release:zed
+npm run release:jetbrains
```
## Important Notes
1. **VS Code**: The bump script automatically syncs `versions.json` and `package.json`
2. **Zed**: Only uses `versions.json`, no need to touch `package.json`
-3. Each IDE follows its own semantic versioning independently
-4. The system includes automatic fallbacks if `versions.json` is missing
+3. **JetBrains**: Only uses `versions.json`, plugin.xml version is generated
+4. Each IDE follows its own semantic versioning independently
+5. The system includes automatic fallbacks if `versions.json` is missing
## Code API
```typescript
-import { getVSCodeVersion, getZedVersion } from "./version-manager";
+import {
+ getVSCodeVersion,
+ getZedVersion,
+ getJetBrainsVersion,
+ getAllVersions,
+} from "./version-manager";
-const zedVersion = getZedVersion(); // "1.0.0"
const vscodeVersion = getVSCodeVersion(); // "11.0.0"
+const zedVersion = getZedVersion(); // "1.0.0"
+const jetbrainsVersion = getJetBrainsVersion(); // "1.0.0"
+const allVersions = getAllVersions(); // { vscode: "11.0.0", zed: "1.0.0", jetbrains: "1.0.0" }
```
## Benefits
@@ -85,3 +185,4 @@ const vscodeVersion = getVSCodeVersion(); // "11.0.0"
- **Independent releases** for each IDE
- **Clear versioning** that reflects platform-specific changes
- **Flexibility** to evolve each platform at its own pace
+- **Filtered changelogs** showing only relevant changes per IDE
diff --git a/package.json b/package.json
index 8ff90cf..26d1e4a 100644
--- a/package.json
+++ b/package.json
@@ -17,25 +17,21 @@
"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:vscode": "npm run build:vscode && vsce package --out ./releases/vscode/%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",
+ "build:ext:jetbrains": "npm run build:jetbrains && node -e \"const{execSync}=require('child_process');const{existsSync,mkdirSync,copyFileSync,readdirSync}=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'});const distDir=join(dir,'build','distributions');const releaseDir=join(process.cwd(),'releases','jetbrains');if(!existsSync(releaseDir))mkdirSync(releaseDir,{recursive:true});const zips=readdirSync(distDir).filter(f=>f.endsWith('.zip'));zips.forEach(z=>{copyFileSync(join(distDir,z),join(releaseDir,z));console.log('Copied to releases/jetbrains/'+z)})\"",
"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",
- "create:release-notes": "vite-node src/create-release-notes.ts",
"bump:version": "vite-node src/bump-version.ts",
- "publish:vscode": "bash -c \"read -p 'Enter your VS Code Marketplace token: ' TOKEN && vsce publish --packagePath ./releases/%npm_package_version%.vsix -p $TOKEN\"",
- "publish:ovsx": "bash -c \"read -p 'Enter your OVSX token: ' TOKEN && ovsx publish ./releases/%npm_package_version%.vsix -p $TOKEN\"",
- "publish:all": "npm run build:ext:vscode && npm run publish:vscode && npm run publish:ovsx"
+ "create:release-notes": "vite-node src/create-release-notes.ts",
+ "release:vscode": "node -e \"const v=require('./versions.json').vscode;const{execSync}=require('child_process');execSync('gh release create vscode-v'+v+' --notes-file ./releases/vscode/'+v+'.md --generate-notes',{stdio:'inherit'})\"",
+ "release:zed": "node -e \"const v=require('./versions.json').zed;const{execSync}=require('child_process');execSync('gh release create zed-v'+v+' --notes-file ./releases/zed/'+v+'.md --generate-notes',{stdio:'inherit'})\"",
+ "release:jetbrains": "node -e \"const v=require('./versions.json').jetbrains;const{execSync}=require('child_process');execSync('gh release create jetbrains-v'+v+' --notes-file ./releases/jetbrains/'+v+'.md --generate-notes',{stdio:'inherit'})\"",
+ "publish:vscode": "bash -c \"read -p 'Enter your VS Code Marketplace token: ' TOKEN && vsce publish --packagePath ./releases/vscode/%npm_package_version%.vsix -p $TOKEN\"",
+ "publish:ovsx": "bash -c \"read -p 'Enter your OVSX token: ' TOKEN && ovsx publish ./releases/vscode/%npm_package_version%.vsix -p $TOKEN\""
},
"__metadata": {
"id": "dffaf5a1-2219-434b-9d87-cb586fd59260",
diff --git a/publish.bat b/publish.bat
deleted file mode 100644
index 4816bfc..0000000
--- a/publish.bat
+++ /dev/null
@@ -1,114 +0,0 @@
-@echo off
-setlocal enabledelayedexpansion
-
-REM Colors for better readability
-set "GREEN=[0;32m"
-set "BLUE=[0;34m"
-set "YELLOW=[1;33m"
-set "RED=[0;31m"
-set "NC=[0m"
-
-REM Get version from package.json using node
-for /f "tokens=*" %%a in ('node -p "require('./package.json').version"') do set VERSION=%%a
-set RELEASE_NOTES=./releases/%VERSION%.md
-
-echo !BLUE!^=== Bearded Theme Release Process ===!NC!
-echo !BLUE!Version: !GREEN!v%VERSION%!NC!
-
-REM Check if VSIX version already exists
-if exist "./releases/%VERSION%.vsix" (
- echo !YELLOW!VSIX file for v%VERSION% already exists.!NC!
- set /p REBUILD="Do you want to rebuild the package? (y/n) "
- echo.
- if /i "!REBUILD!"=="y" (
- echo !BLUE!Building VSIX package...!NC!
- call npm run build:ext
- )
-) else (
- echo !BLUE!Building VSIX package...!NC!
- call npm run build:ext
-)
-
-REM Check if release notes file exists
-if not exist "%RELEASE_NOTES%" (
- echo !YELLOW!Release notes file not found.!NC!
- set /p CREATE_NOTES="Do you want to create a release notes template? (y/n) "
- echo.
- if /i "!CREATE_NOTES!"=="y" (
- echo !BLUE!Creating release notes file...!NC!
- call npm run create:release-notes
- echo !GREEN!✓ Release notes file created: %RELEASE_NOTES%!NC!
- echo !YELLOW!Please edit the release notes file before continuing.!NC!
- echo Press Enter when you have finished editing...
- pause > nul
- echo.
- )
-) else (
- echo !GREEN!✓ Release notes file found: %RELEASE_NOTES%!NC!
-)
-
-REM Publish to VS Code Marketplace
-echo !BLUE!Publishing to VS Code Marketplace...!NC!
-if defined VSCE_PAT (
- echo !GREEN!✓ VSCE token found in environment variables!NC!
- call npm run publish:vscode
-) else (
- echo !YELLOW!VSCE token not found in environment variables!NC!
- set /p HAS_TOKEN="Do you have a VSCE token? (y/n) "
- echo.
- if /i "!HAS_TOKEN!"=="y" (
- set /p VSCE_TOKEN="Enter your VS Code Marketplace token: "
- echo.
- if defined VSCE_TOKEN (
- set "VSCE_PAT=!VSCE_TOKEN!"
- call npm run publish:vscode
- ) else (
- echo !RED!Empty token, VS Code Marketplace publication cancelled.!NC!
- )
- ) else (
- set /p TRY_PUBLISH="Do you still want to try publishing to VS Code Marketplace? (y/n) "
- echo.
- if /i "!TRY_PUBLISH!"=="y" (
- call npm run publish:vscode
- ) else (
- echo !YELLOW!VS Code Marketplace publication skipped.!NC!
- )
- )
-)
-
-REM Publish to Open VSX
-echo !BLUE!Publishing to Open VSX...!NC!
-if defined OVSX_TOKEN (
- echo !GREEN!✓ Open VSX token found in environment variables!NC!
- call npm run publish:ovsx
-) else (
- echo !YELLOW!Open VSX token not found in environment variables!NC!
- set /p HAS_OVSX_TOKEN="Do you have an Open VSX token? (y/n) "
- echo.
- if /i "!HAS_OVSX_TOKEN!"=="y" (
- set /p OVSX_TOKEN_VALUE="Enter your Open VSX token: "
- echo.
- if defined OVSX_TOKEN_VALUE (
- set "OVSX_TOKEN=!OVSX_TOKEN_VALUE!"
- call npm run publish:ovsx
- ) else (
- echo !RED!Empty token, Open VSX publication cancelled.!NC!
- )
- ) else (
- echo !YELLOW!Open VSX publication skipped.!NC!
- )
-)
-
-REM Create GitHub version tag
-echo !BLUE!Creating GitHub version tag...!NC!
-set /p CREATE_TAG="Do you want to create a GitHub tag for this version? (y/n) "
-echo.
-if /i "!CREATE_TAG!"=="y" (
- call npm run release
- echo !GREEN!✓ Tag v%VERSION% created on GitHub!NC!
-) else (
- echo !YELLOW!GitHub tag creation skipped.!NC!
-)
-
-echo !GREEN!^=== Publication process completed ===!NC!
-endlocal
diff --git a/publish.sh b/publish.sh
index f3ebe03..012d369 100644
--- a/publish.sh
+++ b/publish.sh
@@ -7,103 +7,233 @@ YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
-# Get version from package.json
-VERSION=$(node -p "require('./package.json').version")
-RELEASE_NOTES="./releases/$VERSION.md"
-
-echo -e "${BLUE}=== Bearded Theme Release Process ===${NC}"
-echo -e "${BLUE}Version: ${GREEN}v$VERSION${NC}"
-
-# Check if VSIX version already exists
-if [ -f "./releases/$VERSION.vsix" ]; then
- echo -e "${YELLOW}VSIX file for v$VERSION already exists.${NC}"
- read -p "Do you want to rebuild the package? (y/n) " -n 1 -r
- echo
- if [[ $REPLY =~ ^[Yy]$ ]]; then
+# ==========================================
+# VS Code publication
+# ==========================================
+publish_vscode() {
+ # Check if VSIX version already exists
+ if [ -f "./releases/vscode/$VERSION.vsix" ]; then
+ echo -e "${YELLOW}VSIX file for v$VERSION already exists.${NC}"
+ read -p "Do you want to rebuild the package? (y/n) " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo -e "${BLUE}Building VSIX package...${NC}"
+ npm run build:ext:vscode
+ fi
+ else
echo -e "${BLUE}Building VSIX package...${NC}"
- npm run build:ext
+ npm run build:ext:vscode
fi
-else
- echo -e "${BLUE}Building VSIX package...${NC}"
- npm run build:ext
-fi
-# Check if release notes file exists
-if [ ! -f "$RELEASE_NOTES" ]; then
- echo -e "${YELLOW}Release notes file not found.${NC}"
- read -p "Do you want to create a release notes template? (y/n) " -n 1 -r
- echo
- if [[ $REPLY =~ ^[Yy]$ ]]; then
- echo -e "${BLUE}Creating release notes file...${NC}"
- npm run create:release-notes
- echo -e "${GREEN}✓ Release notes file created: $RELEASE_NOTES${NC}"
- echo -e "${YELLOW}Please edit the release notes file before continuing.${NC}"
- read -p "Press Enter when you have finished editing..." -n 1 -r
+ # Check if release notes file exists
+ if [ ! -f "$RELEASE_NOTES" ]; then
+ echo -e "${YELLOW}Release notes file not found.${NC}"
+ read -p "Do you want to create a release notes template? (y/n) " -n 1 -r
echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo -e "${BLUE}Creating release notes file...${NC}"
+ npm run create:release-notes vscode
+ echo -e "${GREEN}✓ Release notes file created: $RELEASE_NOTES${NC}"
+ echo -e "${YELLOW}Please edit the release notes file before continuing.${NC}"
+ read -p "Press Enter when you have finished editing..." -n 1 -r
+ echo
+ fi
+ else
+ echo -e "${GREEN}✓ Release notes file found: $RELEASE_NOTES${NC}"
fi
-else
- echo -e "${GREEN}✓ Release notes file found: $RELEASE_NOTES${NC}"
-fi
-# Publish to VS Code Marketplace
-echo -e "${BLUE}Publishing to VS Code Marketplace...${NC}"
-if [ -n "$VSCE_PAT" ]; then
- echo -e "${GREEN}✓ VSCE token found in environment variables${NC}"
- npm run publish:vscode
-else
- echo -e "${YELLOW}VSCE token not found in environment variables${NC}"
- read -p "Do you have a VSCE token? (y/n) " -n 1 -r
- echo
- if [[ $REPLY =~ ^[Yy]$ ]]; then
- read -p "Enter your VS Code Marketplace token: " VSCE_TOKEN
+ # Publish to VS Code Marketplace
+ echo -e "${BLUE}Publishing to VS Code Marketplace...${NC}"
+ if [ -n "$VSCE_PAT" ]; then
+ echo -e "${GREEN}✓ VSCE token found in environment variables${NC}"
+ npm run publish:vscode
+ else
+ echo -e "${YELLOW}VSCE token not found in environment variables${NC}"
+ read -p "Do you have a VSCE token? (y/n) " -n 1 -r
echo
- if [ -n "$VSCE_TOKEN" ]; then
- VSCE_PAT=$VSCE_TOKEN npm run publish:vscode
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ read -p "Enter your VS Code Marketplace token: " VSCE_TOKEN
+ echo
+ if [ -n "$VSCE_TOKEN" ]; then
+ VSCE_PAT=$VSCE_TOKEN npm run publish:vscode
+ else
+ echo -e "${RED}Empty token, VS Code Marketplace publication cancelled.${NC}"
+ fi
else
- echo -e "${RED}Empty token, VS Code Marketplace publication cancelled.${NC}"
+ read -p "Do you still want to try publishing to VS Code Marketplace? (y/n) " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ npm run publish:vscode
+ else
+ echo -e "${YELLOW}VS Code Marketplace publication skipped.${NC}"
+ fi
fi
+ fi
+
+ # Publish to Open VSX
+ echo -e "${BLUE}Publishing to Open VSX...${NC}"
+ if [ -n "$OVSX_TOKEN" ]; then
+ echo -e "${GREEN}✓ Open VSX token found in environment variables${NC}"
+ npm run publish:ovsx
else
- read -p "Do you still want to try publishing to VS Code Marketplace? (y/n) " -n 1 -r
+ echo -e "${YELLOW}Open VSX token not found in environment variables${NC}"
+ read -p "Do you have an Open VSX token? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
- npm run publish:vscode
+ read -p "Enter your Open VSX token: " OVSX_TOKEN_VALUE
+ echo
+ if [ -n "$OVSX_TOKEN_VALUE" ]; then
+ OVSX_TOKEN=$OVSX_TOKEN_VALUE npm run publish:ovsx
+ else
+ echo -e "${RED}Empty token, Open VSX publication cancelled.${NC}"
+ fi
else
- echo -e "${YELLOW}VS Code Marketplace publication skipped.${NC}"
+ echo -e "${YELLOW}Open VSX publication skipped.${NC}"
fi
fi
-fi
-# Publish to Open VSX
-echo -e "${BLUE}Publishing to Open VSX...${NC}"
-if [ -n "$OVSX_TOKEN" ]; then
- echo -e "${GREEN}✓ Open VSX token found in environment variables${NC}"
- npm run publish:ovsx
-else
- echo -e "${YELLOW}Open VSX token not found in environment variables${NC}"
- read -p "Do you have an Open VSX token? (y/n) " -n 1 -r
+ # Create GitHub version tag
+ echo -e "${BLUE}Creating GitHub version tag...${NC}"
+ read -p "Do you want to create a GitHub tag for this version? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
- read -p "Enter your Open VSX token: " OVSX_TOKEN_VALUE
+ npm run release:vscode
+ echo -e "${GREEN}✓ Tag vscode-v$VERSION created on GitHub${NC}"
+ else
+ echo -e "${YELLOW}GitHub tag creation skipped.${NC}"
+ fi
+}
+
+# ==========================================
+# Zed publication
+# ==========================================
+publish_zed() {
+ # Build Zed extension
+ echo -e "${BLUE}Building Zed extension...${NC}"
+ npm run build:ext:zed
+
+ # Check if release notes file exists
+ if [ ! -f "$RELEASE_NOTES" ]; then
+ echo -e "${YELLOW}Release notes file not found.${NC}"
+ read -p "Do you want to create a release notes template? (y/n) " -n 1 -r
echo
- if [ -n "$OVSX_TOKEN_VALUE" ]; then
- OVSX_TOKEN=$OVSX_TOKEN_VALUE npm run publish:ovsx
- else
- echo -e "${RED}Empty token, Open VSX publication cancelled.${NC}"
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo -e "${BLUE}Creating release notes file...${NC}"
+ npm run create:release-notes zed
+ echo -e "${GREEN}✓ Release notes file created: $RELEASE_NOTES${NC}"
+ echo -e "${YELLOW}Please edit the release notes file before continuing.${NC}"
+ read -p "Press Enter when you have finished editing..." -n 1 -r
+ echo
+ fi
+ else
+ echo -e "${GREEN}✓ Release notes file found: $RELEASE_NOTES${NC}"
+ fi
+
+ echo ""
+ echo -e "${BLUE}Zed publication steps:${NC}"
+ echo " 1. Extension built in: dist/zed/"
+ echo " 2. Commit and push your changes"
+ echo " 3. Open a PR to zed-industries/extensions repository"
+ echo ""
+
+ # Create GitHub version tag
+ read -p "Do you want to create a GitHub tag for this version? (y/n) " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ npm run release:zed
+ echo -e "${GREEN}✓ Tag zed-v$VERSION created on GitHub${NC}"
+ else
+ echo -e "${YELLOW}GitHub tag creation skipped.${NC}"
+ fi
+}
+
+# ==========================================
+# JetBrains publication
+# ==========================================
+publish_jetbrains() {
+ # Build JetBrains plugin
+ echo -e "${BLUE}Building JetBrains plugin...${NC}"
+ npm run build:ext:jetbrains
+
+ # Check if release notes file exists
+ if [ ! -f "$RELEASE_NOTES" ]; then
+ echo -e "${YELLOW}Release notes file not found.${NC}"
+ read -p "Do you want to create a release notes template? (y/n) " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo -e "${BLUE}Creating release notes file...${NC}"
+ npm run create:release-notes jetbrains
+ echo -e "${GREEN}✓ Release notes file created: $RELEASE_NOTES${NC}"
+ echo -e "${YELLOW}Please edit the release notes file before continuing.${NC}"
+ read -p "Press Enter when you have finished editing..." -n 1 -r
+ echo
fi
else
- echo -e "${YELLOW}Open VSX publication skipped.${NC}"
+ echo -e "${GREEN}✓ Release notes file found: $RELEASE_NOTES${NC}"
fi
+
+ echo ""
+ echo -e "${BLUE}JetBrains publication steps:${NC}"
+ echo " 1. Plugin built in: releases/jetbrains/"
+ echo " 2. Go to https://plugins.jetbrains.com/"
+ echo " 3. Upload the ZIP file manually"
+ echo ""
+
+ # Create GitHub version tag
+ read -p "Do you want to create a GitHub tag for this version? (y/n) " -n 1 -r
+ echo
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
+ npm run release:jetbrains
+ echo -e "${GREEN}✓ Tag jetbrains-v$VERSION created on GitHub${NC}"
+ else
+ echo -e "${YELLOW}GitHub tag creation skipped.${NC}"
+ fi
+}
+
+# ==========================================
+# Main script
+# ==========================================
+
+# Check for IDE argument
+if [ -z "$1" ]; then
+ echo -e "${RED}Usage: ./publish.sh ${NC}"
+ echo " ide: vscode | zed | jetbrains"
+ echo ""
+ echo "Examples:"
+ echo " ./publish.sh vscode"
+ echo " ./publish.sh zed"
+ echo " ./publish.sh jetbrains"
+ exit 1
fi
-# Create GitHub version tag
-echo -e "${BLUE}Creating GitHub version tag...${NC}"
-read -p "Do you want to create a GitHub tag for this version? (y/n) " -n 1 -r
-echo
-if [[ $REPLY =~ ^[Yy]$ ]]; then
- npm run release
- echo -e "${GREEN}✓ Tag v$VERSION created on GitHub${NC}"
-else
- echo -e "${YELLOW}GitHub tag creation skipped.${NC}"
+IDE=$1
+
+# Validate IDE argument
+if [[ ! "$IDE" =~ ^(vscode|zed|jetbrains)$ ]]; then
+ echo -e "${RED}Invalid IDE: $IDE${NC}"
+ echo " Must be: vscode | zed | jetbrains"
+ exit 1
fi
+# Get version from versions.json
+VERSION=$(node -p "require('./versions.json').$IDE")
+RELEASE_NOTES="./releases/$IDE/$VERSION.md"
+
+echo -e "${BLUE}=== Bearded Theme Release Process ===${NC}"
+echo -e "${BLUE}IDE: ${GREEN}$IDE${NC}"
+echo -e "${BLUE}Version: ${GREEN}v$VERSION${NC}"
+
+# IDE-specific publication
+case $IDE in
+ vscode)
+ publish_vscode
+ ;;
+ zed)
+ publish_zed
+ ;;
+ jetbrains)
+ publish_jetbrains
+ ;;
+esac
+
echo -e "${GREEN}=== Publication process completed ===${NC}"
diff --git a/releases/jetbrains/.gitkeep b/releases/jetbrains/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/releases/10.0.0.md b/releases/vscode/10.0.0.md
similarity index 100%
rename from releases/10.0.0.md
rename to releases/vscode/10.0.0.md
diff --git a/releases/10.1.0.md b/releases/vscode/10.1.0.md
similarity index 100%
rename from releases/10.1.0.md
rename to releases/vscode/10.1.0.md
diff --git a/releases/8.3.2.md b/releases/vscode/8.3.2.md
similarity index 100%
rename from releases/8.3.2.md
rename to releases/vscode/8.3.2.md
diff --git a/releases/9.0.0.md b/releases/vscode/9.0.0.md
similarity index 100%
rename from releases/9.0.0.md
rename to releases/vscode/9.0.0.md
diff --git a/releases/9.0.1.md b/releases/vscode/9.0.1.md
similarity index 100%
rename from releases/9.0.1.md
rename to releases/vscode/9.0.1.md
diff --git a/releases/9.1.0.md b/releases/vscode/9.1.0.md
similarity index 100%
rename from releases/9.1.0.md
rename to releases/vscode/9.1.0.md
diff --git a/releases/9.1.1.md b/releases/vscode/9.1.1.md
similarity index 100%
rename from releases/9.1.1.md
rename to releases/vscode/9.1.1.md
diff --git a/releases/9.1.2.md b/releases/vscode/9.1.2.md
similarity index 100%
rename from releases/9.1.2.md
rename to releases/vscode/9.1.2.md
diff --git a/releases/9.1.3.md b/releases/vscode/9.1.3.md
similarity index 100%
rename from releases/9.1.3.md
rename to releases/vscode/9.1.3.md
diff --git a/releases/9.1.4.md b/releases/vscode/9.1.4.md
similarity index 100%
rename from releases/9.1.4.md
rename to releases/vscode/9.1.4.md
diff --git a/releases/9.1.5.md b/releases/vscode/9.1.5.md
similarity index 100%
rename from releases/9.1.5.md
rename to releases/vscode/9.1.5.md
diff --git a/releases/9.2.0.md b/releases/vscode/9.2.0.md
similarity index 100%
rename from releases/9.2.0.md
rename to releases/vscode/9.2.0.md
diff --git a/releases/9.3.0.md b/releases/vscode/9.3.0.md
similarity index 100%
rename from releases/9.3.0.md
rename to releases/vscode/9.3.0.md
diff --git a/releases/zed/.gitkeep b/releases/zed/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/bump-version.ts b/src/bump-version.ts
index 22070c0..670ef9b 100644
--- a/src/bump-version.ts
+++ b/src/bump-version.ts
@@ -9,12 +9,13 @@ type BumpType = "major" | "minor" | "patch";
/**
* IDE types
*/
-type IDE = "all" | "vscode" | "zed";
+type IDE = "all" | "jetbrains" | "vscode" | "zed";
/**
* Version configuration interface
*/
interface VersionConfig {
+ jetbrains: string;
vscode: string;
zed: string;
}
@@ -45,17 +46,20 @@ function main(): void {
if (args.length !== 2) {
console.error("Usage: npm run bump:version ");
- console.error(" ide: vscode | zed | all");
+ console.error(" ide: vscode | zed | jetbrains | all");
console.error(" type: major | minor | patch");
console.error("");
console.error("Examples:");
console.error(
- " npm run bump:version zed patch # Bump Zed from 1.0.0 to 1.0.1",
+ " npm run bump:version zed patch # Bump Zed from 1.0.0 to 1.0.1",
);
console.error(
- " npm run bump:version vscode minor # Bump VS Code from 11.0.0 to 11.1.0",
+ " npm run bump:version vscode minor # Bump VS Code from 11.0.0 to 11.1.0",
);
- console.error(" npm run bump:version all patch # Bump both IDEs");
+ console.error(
+ " npm run bump:version jetbrains patch # Bump JetBrains from 1.0.0 to 1.0.1",
+ );
+ console.error(" npm run bump:version all patch # Bump all IDEs");
process.exit(1);
}
@@ -63,9 +67,9 @@ function main(): void {
const bumpType = args[1] as BumpType;
// Validate arguments
- if (!["all", "vscode", "zed"].includes(ide)) {
+ if (!["all", "jetbrains", "vscode", "zed"].includes(ide)) {
console.error(`❌ Invalid IDE: ${ide}`);
- console.error(" Must be: vscode | zed | all");
+ console.error(" Must be: vscode | zed | jetbrains | all");
process.exit(1);
}
@@ -79,8 +83,9 @@ function main(): void {
// Read current versions
const versions = readVersionConfig();
console.log("📦 Current versions:");
- console.log(` VS Code: ${versions.vscode}`);
- console.log(` Zed: ${versions.zed}`);
+ console.log(` VS Code: ${versions.vscode}`);
+ console.log(` Zed: ${versions.zed}`);
+ console.log(` JetBrains: ${versions.jetbrains}`);
console.log("");
// Bump versions
@@ -101,7 +106,14 @@ function main(): void {
const oldVersion = versions.zed;
const newVersion = bumpVersion(oldVersion, bumpType);
versions.zed = newVersion;
- console.log(`✅ Zed: ${oldVersion} → ${newVersion}`);
+ console.log(`✅ Zed: ${oldVersion} → ${newVersion}`);
+ }
+
+ if (ide === "jetbrains" || ide === "all") {
+ const oldVersion = versions.jetbrains;
+ const newVersion = bumpVersion(oldVersion, bumpType);
+ versions.jetbrains = newVersion;
+ console.log(`✅ JetBrains: ${oldVersion} → ${newVersion}`);
}
// Save updated versions
@@ -112,17 +124,33 @@ function main(): void {
console.log("📝 Next steps:");
if (ide === "vscode" || ide === "all") {
+ console.log("");
+ console.log(" VS Code:");
console.log(" 1. Run: npm run build:vscode");
- console.log(" 2. Run: npm run create:release-notes");
- console.log(` 3. Edit: releases/${versions.vscode}.md`);
+ console.log(" 2. Run: npm run create:release-notes vscode");
+ console.log(` 3. Edit: releases/vscode/${versions.vscode}.md`);
console.log(" 4. Run: npm run build:ext:vscode");
- console.log(" 5. Run: npm run publish:all");
+ console.log(" 5. Run: publish.bat vscode");
}
if (ide === "zed" || ide === "all") {
+ console.log("");
+ console.log(" Zed:");
console.log(" 1. Run: npm run build:zed");
- console.log(" 2. Commit and push changes");
- console.log(" 3. Open PR to zed-industries/extensions");
+ console.log(" 2. Run: npm run create:release-notes zed");
+ console.log(` 3. Edit: releases/zed/${versions.zed}.md`);
+ console.log(" 4. Commit and push changes");
+ console.log(" 5. Open PR to zed-industries/extensions");
+ }
+
+ if (ide === "jetbrains" || ide === "all") {
+ console.log("");
+ console.log(" JetBrains:");
+ console.log(" 1. Run: npm run build:jetbrains");
+ console.log(" 2. Run: npm run create:release-notes jetbrains");
+ console.log(` 3. Edit: releases/jetbrains/${versions.jetbrains}.md`);
+ console.log(" 4. Run: npm run build:ext:jetbrains");
+ console.log(" 5. Run: publish.bat jetbrains");
}
} catch (error) {
console.error("❌ Error:", error);
diff --git a/src/create-release-notes.ts b/src/create-release-notes.ts
index 44e95a3..5fadbdb 100644
--- a/src/create-release-notes.ts
+++ b/src/create-release-notes.ts
@@ -3,20 +3,45 @@ import * as fs from "fs";
import * as path from "path";
/**
- * Creates release notes for the current version of the package
+ * IDE types
*/
-const createReleaseNotes = (): void => {
+type IDE = "jetbrains" | "vscode" | "zed";
+
+/**
+ * Version configuration interface
+ */
+interface VersionConfig {
+ jetbrains: string;
+ vscode: string;
+ zed: string;
+}
+
+/**
+ * Read versions.json
+ */
+function readVersionConfig(): VersionConfig {
+ const versionsPath = path.resolve(process.cwd(), "versions.json");
+ return JSON.parse(fs.readFileSync(versionsPath, "utf8"));
+}
+
+/**
+ * Creates release notes for a specific IDE
+ */
+const createReleaseNotes = (ide: IDE): void => {
try {
- // Get the current package version from package.json
- const packagePath = path.resolve(process.cwd(), "package.json");
- const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
- const version = packageJson.version;
+ // Get the version for the specified IDE from versions.json
+ const versions = readVersionConfig();
+ const version = versions[ide];
// Get the current branch
const branch = execSync("git branch --show-current").toString().trim();
- // Create the output path
- const outputPath = path.resolve(process.cwd(), "releases", `${version}.md`);
+ // Create the output directory and path
+ const outputDir = path.resolve(process.cwd(), "releases", ide);
+ if (!fs.existsSync(outputDir)) {
+ fs.mkdirSync(outputDir, { recursive: true });
+ }
+ const outputPath = path.resolve(outputDir, `${version}.md`);
// Create the header with version and date
const today = new Date();
@@ -26,16 +51,25 @@ const createReleaseNotes = (): void => {
// Fetch all tags
execSync("git fetch --tags");
- // Check if there are previous tags
+ // Check if there are previous tags for this IDE
let hasPreviousTag = false;
let lastTag = "";
try {
- // Use a more Windows-friendly approach to check for tags
- const tagsOutput = execSync("git tag -l").toString().trim();
- hasPreviousTag = tagsOutput.length > 0;
-
- if (hasPreviousTag) {
- lastTag = execSync("git describe --tags --abbrev=0").toString().trim();
+ // Look for IDE-specific tags first, then fall back to any tag
+ const tagsOutput = execSync(`git tag -l "${ide}-v*"`).toString().trim();
+ if (tagsOutput.length > 0) {
+ // Get the most recent IDE-specific tag
+ lastTag = execSync(`git describe --tags --abbrev=0 --match "${ide}-v*"`)
+ .toString()
+ .trim();
+ hasPreviousTag = true;
+ } else {
+ // Fall back to any tag
+ const anyTagsOutput = execSync("git tag -l").toString().trim();
+ hasPreviousTag = anyTagsOutput.length > 0;
+ if (hasPreviousTag) {
+ lastTag = execSync("git describe --tags --abbrev=0").toString().trim();
+ }
}
} catch (error) {
console.error("Error checking for tags:", error);
@@ -94,6 +128,26 @@ const createReleaseNotes = (): void => {
return commit;
};
+ // Function to check if a commit is relevant for the current IDE
+ const isRelevantForIDE = (commit: string): boolean => {
+ // Check for IDE-specific prefixes: [vscode], [zed], [jetbrains]
+ const idePrefixMatch = commit.match(/^\[(\w+)\]/);
+
+ if (idePrefixMatch) {
+ // If commit has an IDE prefix, only include if it matches current IDE
+ const commitIDE = idePrefixMatch[1].toLowerCase();
+ return commitIDE === ide;
+ }
+
+ // Commits without IDE prefix are global (included in all IDEs)
+ return true;
+ };
+
+ // Function to remove IDE prefix from commit message
+ const removeIDEPrefix = (commit: string): string => {
+ return commit.replace(/^\[\w+\]\s*/, "");
+ };
+
// Function to get all commits between two points
const getAllCommits = (): string[] => {
try {
@@ -108,7 +162,8 @@ const createReleaseNotes = (): void => {
return [];
}
- return allCommits.split("\n");
+ // Filter commits relevant for this IDE
+ return allCommits.split("\n").filter(isRelevantForIDE);
} catch (error) {
console.error("Error getting commits:", error);
return [];
@@ -133,10 +188,15 @@ const createReleaseNotes = (): void => {
return false;
}
+ // Remove IDE prefix for pattern matching
+ const commitWithoutIDEPrefix = removeIDEPrefix(commit);
+
// Check if commit matches any of the patterns
const matches = patternPrefixes.some((prefix) => {
const cleanPrefix = prefix.trim();
- return commit.toLowerCase().startsWith(cleanPrefix.toLowerCase());
+ return commitWithoutIDEPrefix
+ .toLowerCase()
+ .startsWith(cleanPrefix.toLowerCase());
});
// If it matches, mark it as processed
@@ -149,11 +209,13 @@ const createReleaseNotes = (): void => {
// Format the filtered commits
const processedLines = filteredCommits.map((line) => {
+ // Remove IDE prefix first
+ let cleanedLine = removeIDEPrefix(line);
+
// Process the line to extract issue numbers and format them correctly
- const processedLine = extractIssueNumbers(line);
+ cleanedLine = extractIssueNumbers(cleanedLine);
// Remove the commit type prefix (e.g., "fix: ", "feat: ")
- let cleanedLine = processedLine;
patternPrefixes.forEach((prefix) => {
const prefixRegex = new RegExp(`^${prefix}\\s*:\\s*`, "i");
cleanedLine = cleanedLine.replace(prefixRegex, "");
@@ -180,8 +242,11 @@ const createReleaseNotes = (): void => {
if (features.length > 0) {
content += `### Features and Improvements\n\n${features.join("\n")}\n\n`;
} else {
- content += "### Features and Improvements\n\nNo new features or improvements in this release.\n\n";
- } // Get bug fixes
+ content +=
+ "### Features and Improvements\n\nNo new features or improvements in this release.\n\n";
+ }
+
+ // Get bug fixes
const bugsPattern = "^fix\\|^bug";
const bugfixes = getCommits(bugsPattern);
if (bugfixes.length > 0) {
@@ -204,5 +269,38 @@ const createReleaseNotes = (): void => {
}
};
-// Run the function when the script is executed
-createReleaseNotes();
+// Main function
+function main(): void {
+ const args = process.argv.slice(2);
+
+ if (args.length !== 1) {
+ console.error("Usage: npm run create:release-notes ");
+ console.error(" ide: vscode | zed | jetbrains");
+ console.error("");
+ console.error("Examples:");
+ console.error(" npm run create:release-notes vscode");
+ console.error(" npm run create:release-notes zed");
+ console.error(" npm run create:release-notes jetbrains");
+ console.error("");
+ console.error("Commit prefix convention:");
+ console.error(" [vscode] feat: VS Code specific feature");
+ console.error(" [zed] fix: Zed specific fix");
+ console.error(" [jetbrains] add: JetBrains specific addition");
+ console.error(" feat: Global feature (included in all IDEs)");
+ process.exit(1);
+ }
+
+ const ide = args[0] as IDE;
+
+ // Validate arguments
+ if (!["jetbrains", "vscode", "zed"].includes(ide)) {
+ console.error(`Invalid IDE: ${ide}`);
+ console.error(" Must be: vscode | zed | jetbrains");
+ process.exit(1);
+ }
+
+ createReleaseNotes(ide);
+}
+
+// Run the script
+main();
From 5088fe04f9c4399c0b56a8460619c0d59e49bff5 Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Wed, 21 Jan 2026 23:31:39 +0100
Subject: [PATCH 7/9] Drop CHANGELOG and plugin.xml
Add additional fs helpers to src/build.ts
Import copyFileSync, mkdirSync, readdirSync and readFileSync
---
META-INF/plugin.xml | 81 --------------------
releases/jetbrains/1.0.0.md | 36 +++++++++
releases/vscode/11.0.0.md | 36 +++++++++
CHANGELOG.md => releases/vscode/CHANGELOG.md | 0
releases/zed/1.0.0.md | 36 +++++++++
src/build.ts | 31 +++++++-
6 files changed, 137 insertions(+), 83 deletions(-)
delete mode 100644 META-INF/plugin.xml
create mode 100644 releases/jetbrains/1.0.0.md
create mode 100644 releases/vscode/11.0.0.md
rename CHANGELOG.md => releases/vscode/CHANGELOG.md (100%)
create mode 100644 releases/zed/1.0.0.md
diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml
deleted file mode 100644
index 115bed5..0000000
--- a/META-INF/plugin.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
- com.beardedtheme.jetbrains
- Bearded Theme
- 1.0.0
- BeardedBear
-
-
-
- com.intellij.modules.platform
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/releases/jetbrains/1.0.0.md b/releases/jetbrains/1.0.0.md
new file mode 100644
index 0000000..a9e75e6
--- /dev/null
+++ b/releases/jetbrains/1.0.0.md
@@ -0,0 +1,36 @@
+## 1.0.0 - 2026-01-21
+
+### Features and Improvements
+
+- Add .claude to .gitignore
+- Add JetBrains bookmark UI keys
+- Add JetBrains theme generator
+- Add zed dist
+- Add borders and version control colors to Zed UI
+- Add Zed theme generator
+- Add versioning support and bump script
+- Add editor.subheader and search.active styles for Zed
+- Add Zed publish/dev scripts and generator updates
+- Add AGENTS.md with AI agent guidelines
+- Add Zed support and update build scripts
+- Add new experimental variation : OLED [#207 (Thanks @Nova38)](https://github.com/BeardedBear/bearded-theme/issues/207)
+- Improve contrast for light theme
+- Improve publish process
+- Add inline suggest support
+- Add scmGraph foreground support
+
+### Bug Fixes
+
+- Fix Zed theme text and ignored color mappings
+- Fix python doc string contrast [#203 (Thanks @johnReeferVermont)](https://github.com/BeardedBear/bearded-theme/issues/203)
+- Fix inlay hint colors [#201 (Thanks @Oracynx)](https://github.com/BeardedBear/bearded-theme/issues/201)
+- Fix bash evaluation and pipe colors [#169 (Thanks @Wheels35)](https://github.com/BeardedBear/bearded-theme/issues/169)
+- Fix window control hover in linux [#204 (Thanks @PavelDobCZ23)](https://github.com/BeardedBear/bearded-theme/issues/204)
+- Fix status bar item contrast [#195 (Thanks @Loskir)](https://github.com/BeardedBear/bearded-theme/issues/195)
+- Fix list background hover contrast
+- Fix Icons in popup dialogs have unnatural colors [#165 (Thanks @Loskir)](https://github.com/BeardedBear/bearded-theme/issues/165)
+- Fix tab foreground color with no modifications [#205 (Thanks @lperson)](https://github.com/BeardedBear/bearded-theme/issues/205)
+- Fix toolbar icon background
+- Fix Don't distribute image assets within extension package [#196 (Thanks @stevenlele)](https://github.com/BeardedBear/bearded-theme/issues/196)
+- Fix links color
+
diff --git a/releases/vscode/11.0.0.md b/releases/vscode/11.0.0.md
new file mode 100644
index 0000000..dda95a8
--- /dev/null
+++ b/releases/vscode/11.0.0.md
@@ -0,0 +1,36 @@
+## 11.0.0 - 2026-01-21
+
+### Features and Improvements
+
+- Add .claude to .gitignore
+- Add JetBrains bookmark UI keys
+- Add JetBrains theme generator
+- Add zed dist
+- Add borders and version control colors to Zed UI
+- Add Zed theme generator
+- Add versioning support and bump script
+- Add editor.subheader and search.active styles for Zed
+- Add Zed publish/dev scripts and generator updates
+- Add AGENTS.md with AI agent guidelines
+- Add Zed support and update build scripts
+- Add new experimental variation : OLED [#207 (Thanks @Nova38)](https://github.com/BeardedBear/bearded-theme/issues/207)
+- Improve contrast for light theme
+- Improve publish process
+- Add inline suggest support
+- Add scmGraph foreground support
+
+### Bug Fixes
+
+- Fix Zed theme text and ignored color mappings
+- Fix python doc string contrast [#203 (Thanks @johnReeferVermont)](https://github.com/BeardedBear/bearded-theme/issues/203)
+- Fix inlay hint colors [#201 (Thanks @Oracynx)](https://github.com/BeardedBear/bearded-theme/issues/201)
+- Fix bash evaluation and pipe colors [#169 (Thanks @Wheels35)](https://github.com/BeardedBear/bearded-theme/issues/169)
+- Fix window control hover in linux [#204 (Thanks @PavelDobCZ23)](https://github.com/BeardedBear/bearded-theme/issues/204)
+- Fix status bar item contrast [#195 (Thanks @Loskir)](https://github.com/BeardedBear/bearded-theme/issues/195)
+- Fix list background hover contrast
+- Fix Icons in popup dialogs have unnatural colors [#165 (Thanks @Loskir)](https://github.com/BeardedBear/bearded-theme/issues/165)
+- Fix tab foreground color with no modifications [#205 (Thanks @lperson)](https://github.com/BeardedBear/bearded-theme/issues/205)
+- Fix toolbar icon background
+- Fix Don't distribute image assets within extension package [#196 (Thanks @stevenlele)](https://github.com/BeardedBear/bearded-theme/issues/196)
+- Fix links color
+
diff --git a/CHANGELOG.md b/releases/vscode/CHANGELOG.md
similarity index 100%
rename from CHANGELOG.md
rename to releases/vscode/CHANGELOG.md
diff --git a/releases/zed/1.0.0.md b/releases/zed/1.0.0.md
new file mode 100644
index 0000000..a9e75e6
--- /dev/null
+++ b/releases/zed/1.0.0.md
@@ -0,0 +1,36 @@
+## 1.0.0 - 2026-01-21
+
+### Features and Improvements
+
+- Add .claude to .gitignore
+- Add JetBrains bookmark UI keys
+- Add JetBrains theme generator
+- Add zed dist
+- Add borders and version control colors to Zed UI
+- Add Zed theme generator
+- Add versioning support and bump script
+- Add editor.subheader and search.active styles for Zed
+- Add Zed publish/dev scripts and generator updates
+- Add AGENTS.md with AI agent guidelines
+- Add Zed support and update build scripts
+- Add new experimental variation : OLED [#207 (Thanks @Nova38)](https://github.com/BeardedBear/bearded-theme/issues/207)
+- Improve contrast for light theme
+- Improve publish process
+- Add inline suggest support
+- Add scmGraph foreground support
+
+### Bug Fixes
+
+- Fix Zed theme text and ignored color mappings
+- Fix python doc string contrast [#203 (Thanks @johnReeferVermont)](https://github.com/BeardedBear/bearded-theme/issues/203)
+- Fix inlay hint colors [#201 (Thanks @Oracynx)](https://github.com/BeardedBear/bearded-theme/issues/201)
+- Fix bash evaluation and pipe colors [#169 (Thanks @Wheels35)](https://github.com/BeardedBear/bearded-theme/issues/169)
+- Fix window control hover in linux [#204 (Thanks @PavelDobCZ23)](https://github.com/BeardedBear/bearded-theme/issues/204)
+- Fix status bar item contrast [#195 (Thanks @Loskir)](https://github.com/BeardedBear/bearded-theme/issues/195)
+- Fix list background hover contrast
+- Fix Icons in popup dialogs have unnatural colors [#165 (Thanks @Loskir)](https://github.com/BeardedBear/bearded-theme/issues/165)
+- Fix tab foreground color with no modifications [#205 (Thanks @lperson)](https://github.com/BeardedBear/bearded-theme/issues/205)
+- Fix toolbar icon background
+- Fix Don't distribute image assets within extension package [#196 (Thanks @stevenlele)](https://github.com/BeardedBear/bearded-theme/issues/196)
+- Fix links color
+
diff --git a/src/build.ts b/src/build.ts
index 1c5dd93..c7372b4 100644
--- a/src/build.ts
+++ b/src/build.ts
@@ -6,7 +6,13 @@
*/
import { execSync } from "child_process";
-import { existsSync } from "fs";
+import {
+ copyFileSync,
+ existsSync,
+ mkdirSync,
+ readdirSync,
+ readFileSync,
+} from "fs";
import { join } from "path";
type BuildTarget = "all" | "jetbrains" | "vscode" | "zed";
@@ -62,8 +68,29 @@ function buildJetBrainsPlugin(): void {
stdio: "inherit",
});
+ // Copy ZIP to releases/jetbrains/ with version number
+ const distDir = join(jetbrainsDir, "build", "distributions");
+ const releaseDir = join(process.cwd(), "releases", "jetbrains");
+
+ if (!existsSync(releaseDir)) {
+ mkdirSync(releaseDir, { recursive: true });
+ }
+
+ // Get version from versions.json
+ const versionsPath = join(process.cwd(), "versions.json");
+ const versions = JSON.parse(readFileSync(versionsPath, "utf8"));
+ const version = versions.jetbrains;
+
+ // Find and copy ZIP files
+ const zips = readdirSync(distDir).filter((f) => f.endsWith(".zip"));
+ zips.forEach((zip) => {
+ const destName = `bearded-theme-${version}.zip`;
+ copyFileSync(join(distDir, zip), join(releaseDir, destName));
+ console.log(`\n 📦 Copied to releases/jetbrains/${destName}`);
+ });
+
console.log("\n✅ JetBrains plugin built successfully!");
- console.log(" Plugin ZIP: dist/jetbrains/build/distributions/\n");
+ console.log(` Plugin ZIP: releases/jetbrains/bearded-theme-${version}.zip\n`);
} catch {
console.warn("\n⚠️ Gradle build failed.");
console.warn(" Check the error messages above for details.");
From 83b12661a06d1523cd22de3192722e79e16e5e7a Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Wed, 21 Jan 2026 23:58:38 +0100
Subject: [PATCH 8/9] Refactor generators to use shared metadata
---
src/generators/jetbrains/index.ts | 135 ++++++++++++++---------------
src/generators/jetbrains/plugin.ts | 51 +++++------
src/generators/vscode/index.ts | 9 +-
src/generators/zed/index.ts | 35 ++++----
src/shared/meta.ts | 68 +++++++++++++++
5 files changed, 179 insertions(+), 119 deletions(-)
create mode 100644 src/shared/meta.ts
diff --git a/src/generators/jetbrains/index.ts b/src/generators/jetbrains/index.ts
index a56393e..222259d 100644
--- a/src/generators/jetbrains/index.ts
+++ b/src/generators/jetbrains/index.ts
@@ -6,21 +6,22 @@
*
* Output structure:
* dist/jetbrains/
- * ├── resources/
- * │ └── META-INF/
- * │ └── plugin.xml
- * ├── themes/
- * │ ├── bearded-theme-{slug}.theme.json
- * │ └── bearded-theme-{slug}.xml (editor schemes)
- * ├── build.gradle.kts
- * ├── settings.gradle.kts
- * ├── gradle.properties
- * └── README.md
+ * ⌂ resources/
+ * ⌂ ⌂ META-INF/
+ * ⌂ ⌂ ⌂ plugin.xml
+ * ⌂ themes/
+ * ⌂ ⌂ bearded-theme-{slug}.theme.json
+ * ⌂ ⌂ bearded-theme-{slug}.xml (editor schemes)
+ * ⌂ build.gradle.kts
+ * ⌂ settings.gradle.kts
+ * ⌂ gradle.properties
+ * ⌂ README.md
*/
import { chmodSync, mkdirSync, writeFileSync } from "fs";
import { join } from "path";
+import { Meta } from "../../shared/meta";
import { themeRegistry, ThemeRegistryEntry } from "../../shared/theme-registry";
import { getJetBrainsVersion } from "../../version-manager";
import { buildEditorScheme } from "./editor-scheme";
@@ -41,7 +42,7 @@ async function buildJetBrainsThemes(): Promise {
// Get version from versions.json
const version = getJetBrainsVersion();
- console.log(`📦 Using JetBrains version: ${version}`);
+ console.log(`Using JetBrains version: ${version}`);
// Ensure output directories exist
mkdirSync(THEMES_DIR, { recursive: true });
@@ -66,13 +67,15 @@ async function buildJetBrainsThemes(): Promise {
generateReadme();
console.log(
- `✅ Generated ${themeRegistry.length} JetBrains themes in ${OUTPUT_DIR}`,
+ `Generated ${themeRegistry.length} JetBrains themes in ${OUTPUT_DIR}`,
);
- console.log(`✅ Generated plugin.xml (version ${version})`);
+ console.log(`Generated plugin.xml (version ${version})`);
console.log("✅ Generated Gradle build files");
console.log("✅ Generated README.md");
- console.log(`\n📁 JetBrains plugin ready in: ${OUTPUT_DIR}/`);
- console.log("\n📝 To build the plugin:");
+ console.log(`
+ JetBrains plugin ready in: ${OUTPUT_DIR}/
+`);
+ console.log("\n To build the plugin:");
console.log(" cd dist/jetbrains");
console.log(" ./gradlew buildPlugin");
console.log("\n The plugin ZIP will be in build/distributions/");
@@ -121,9 +124,9 @@ dependencies {
intellijPlatform {
pluginConfiguration {
- name = "Bearded Theme"
+ name = "${Meta.name}"
version = "${version}"
- description = "The theme with a long beard. A collection of carefully crafted color themes."
+ description = "${Meta.description} A collection of carefully crafted color themes."
changeNotes = "See GitHub releases for changelog."
ideaVersion {
@@ -132,9 +135,9 @@ intellijPlatform {
}
vendor {
- name = "BeardedBear"
- email = "beardedbearbear@gmail.com"
- url = "https://github.com/BeardedBear/bearded-theme"
+ name = "${Meta.author.name}"
+ email = "${Meta.author.email}"
+ url = "${Meta.urls.github}"
}
}
@@ -163,7 +166,7 @@ tasks {
});
// settings.gradle.kts
- const settingsGradle = `rootProject.name = "bearded-theme"
+ const settingsGradle = `rootProject.name = "${Meta.slug}"
pluginManagement {
repositories {
@@ -249,7 +252,7 @@ do
link=\${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
+ *) app_path=$APP_HOME$link ;; #(
esac
done
@@ -295,19 +298,13 @@ if [ -n "$JAVA_HOME" ] ; then
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
- die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation."
fi
fi
@@ -351,8 +348,8 @@ if "$cygwin" || "$msys" ; then
case $arg in #(
-*) false ;; #(
/?*) t=\${arg#)}; t=/\${t%%/*} #(
- [ -e "$t" ] ;;
- *) false ;;
+ [ -e "$t" ] ;; #(
+ *) false ;; #(
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
@@ -372,10 +369,10 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# temporary shell commands that run inside "" and get evaluated
# within "" by the exec below.
# * DEFAULT_JVM_OPTS://
-set -- \\
- "-Dorg.gradle.appname=$APP_BASE_NAME" \\
- -classpath "$CLASSPATH" \\
- org.gradle.wrapper.GradleWrapperMain \\
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xeli" has created that special file indicating that the initialization is complete
@@ -418,7 +415,7 @@ set APP_HOME=%DIRNAME%
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+set DEFAULT_JVM_OPTS "-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -427,11 +424,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+ echo.
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ echo.
+ echo Please set the JAVA_HOME variable in your environment to match the
+ echo location of your Java installation.
goto fail
@@ -441,11 +438,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+ echo.
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+ echo.
+ echo Please set the JAVA_HOME variable in your environment to match the
+ echo location of your Java installation.
goto fail
@@ -490,9 +487,11 @@ if "%OS%"=="Windows_NT" endlocal
* Generate README for the JetBrains plugin
*/
function generateReadme(): void {
- const readmeContent = `# Bearded Theme for JetBrains IDEs
+ const codeBlock = "```";
+
+ const readmeContent = `# ${Meta.name} for JetBrains IDEs
-The theme with a long beard. A collection of carefully crafted color themes for JetBrains IDEs.
+${Meta.description} A collection of carefully crafted color themes for JetBrains IDEs.
## Installation
@@ -500,11 +499,11 @@ The theme with a long beard. A collection of carefully crafted color themes for
1. Open your JetBrains IDE (WebStorm, IntelliJ IDEA, PyCharm, etc.)
2. Go to **Settings/Preferences** → **Plugins** → **Marketplace**
-3. Search for "Bearded Theme"
+3. Search for "${Meta.name}"
4. Click **Install**
5. Restart the IDE
6. Go to **Settings/Preferences** → **Appearance & Behavior** → **Appearance**
-7. Select your preferred Bearded Theme from the Theme dropdown
+7. Select your preferred ${Meta.name} from the Theme dropdown
### From ZIP File (Manual Installation)
@@ -525,7 +524,7 @@ The theme with a long beard. A collection of carefully crafted color themes for
### Build Commands
-\`\`\`bash
+${codeBlock}bash
# Build the plugin
./gradlew buildPlugin
@@ -536,40 +535,34 @@ The theme with a long beard. A collection of carefully crafted color themes for
# Verify plugin compatibility
./gradlew verifyPlugin
-\`\`\`
+${codeBlock}
## Available Themes
-${themeRegistry.map((entry) => `- Bearded Theme ${entry.name}`).join("\n")}
+${themeRegistry.map((entry) => `- ${Meta.name} ${entry.name}`).join(
+ "\n",
+)}
## Theme Categories
-- **Arc** - Clean, modern dark themes
-- **Solarized** - Classic solarized color schemes
-- **Oceanic** - Ocean-inspired color palettes
-- **Monokai** - Monokai-inspired variants
-- **Black & Gems** - Pure black backgrounds with gem accent colors
-- **High Contrast (HC)** - Accessibility-focused themes
-- **Milkshake** - Soft, pastel light themes
-- **Coffee** - Warm, earthy tones
-- **Vivid** - Vibrant, saturated colors
-- **Aquarelle** - Watercolor-inspired themes
-- **Surprising** - Unique, unexpected color combinations
+${Meta.categories.map((c) => `- **${c.name}** - ${c.description}`).join(
+ "\n",
+)}
## Links
-- [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=BeardedBear.beardedtheme)
-- [Zed Extension](https://github.com/BeardedBear/bearded-theme)
-- [GitHub Repository](https://github.com/BeardedBear/bearded-theme)
-- [Report Issues](https://github.com/BeardedBear/bearded-theme/issues)
+- [VS Code Extension](${Meta.urls.marketplace.vscode})
+- [Zed Extension](${Meta.urls.github})
+- [GitHub Repository](${Meta.urls.github})
+- [Report Issues](${Meta.urls.issues})
## License
-GNU General Public License v3.0
+${Meta.license}
## Author
-Made with ❤️ by [BeardedBear](https://github.com/BeardedBear)
+Made with ❤️ by [${Meta.author.name}](https://github.com/${Meta.author.name})
`;
writeFileSync(join(OUTPUT_DIR, "README.md"), readmeContent, {
diff --git a/src/generators/jetbrains/plugin.ts b/src/generators/jetbrains/plugin.ts
index 500ef69..6481d30 100644
--- a/src/generators/jetbrains/plugin.ts
+++ b/src/generators/jetbrains/plugin.ts
@@ -9,6 +9,7 @@
* - https://plugins.jetbrains.com/docs/intellij/developing-themes.html
*/
+import { Meta } from "../../shared/meta";
import { ThemeRegistryEntry } from "../../shared/theme-registry";
/**
@@ -24,9 +25,9 @@ export function generatePluginXml(
): string {
const themeProviders = themes
.map((entry) => {
- const themeId = escapeXml(`bearded-theme-${entry.slug}`);
+ const themeId = escapeXml(`${Meta.slug}-${entry.slug}`);
// Path is relative to JAR root - no /themes/ prefix needed
- const themePath = escapeXml(`/bearded-theme-${entry.slug}.theme.json`);
+ const themePath = escapeXml(`/${Meta.slug}-${entry.slug}.theme.json`);
return ` `${escapeXml(c.name)} - ${escapeXml(c.description)}`)
+ .join("\n ");
+
return `
com.beardedtheme.jetbrains
- Bearded Theme
+ ${Meta.name}
${version}
BeardedBear
+ email="${Meta.author.email}"
+ url="${Meta.urls.github}"
+ >${Meta.author.name}
Bearded Theme
- The theme with a long beard. A collection of carefully crafted color themes for your IDE.
+ ${Meta.name}
+ ${Meta.description} A collection of carefully crafted color themes for your IDE.
Features
- - 60+ theme variants including dark, light, and high contrast options
+ - ${themes.length}+ theme variants including dark, light, and high contrast options
- Carefully designed color palettes for reduced eye strain
- Consistent syntax highlighting across all supported languages
- Support for the new Islands UI theme style
@@ -63,27 +68,19 @@ export function generatePluginXml(
Theme Categories
- - Arc - Clean, modern dark themes
- - Solarized - Classic solarized color schemes
- - Oceanic - Ocean-inspired color palettes
- - Monokai - Monokai-inspired variants
- - Black & Gems - Pure black backgrounds with gem accent colors
- - High Contrast - Accessibility-focused themes
- - Milkshake - Soft, pastel light themes
- - Coffee - Warm, earthy tones
- - And many more...
+ ${categoriesHtml}
Links
]]>
See the GitHub Releases for full changelog.
+ See the GitHub Releases for full changelog.
]]>
@@ -113,9 +110,9 @@ export function getThemeList(
}> {
return themes.map((entry) => ({
dark: !entry.options.light,
- id: `bearded-theme-${entry.slug}`,
- name: `Bearded Theme ${entry.name}`,
- path: `/bearded-theme-${entry.slug}.theme.json`,
+ id: `${Meta.slug}-${entry.slug}`,
+ name: `${Meta.name} ${entry.name}`,
+ path: `/${Meta.slug}-${entry.slug}.theme.json`,
}));
}
diff --git a/src/generators/vscode/index.ts b/src/generators/vscode/index.ts
index b2c71a9..658d7fe 100644
--- a/src/generators/vscode/index.ts
+++ b/src/generators/vscode/index.ts
@@ -1,6 +1,7 @@
import { mkdirSync, writeFile, writeFileSync } from "fs";
import { dirname } from "path";
+import { Meta } from "../../shared/meta";
import {
getVscodeUiTheme,
themeRegistry,
@@ -45,8 +46,8 @@ function generateThemeContributes(): Array<{
uiTheme: string;
}> {
return themeRegistry.map((entry) => ({
- label: `Bearded Theme ${entry.name}`,
- path: `./dist/vscode/themes/bearded-theme-${entry.slug}.json`,
+ label: `${Meta.name} ${entry.name}`,
+ path: `./dist/vscode/themes/${Meta.slug}-${entry.slug}.json`,
uiTheme: getVscodeUiTheme(entry.options),
}));
}
@@ -61,13 +62,13 @@ async function makeVscodeTheme(entry: ThemeRegistryEntry): Promise {
const themeTemplate = {
$schema: "vscode://schemas/color-theme",
colors: ui(theme, hc, light, untindedSelection, desaturateInputs),
- name: `BeardedTheme ${name}`,
+ name: `${Meta.name} ${name}`,
semanticHighlighting: true,
semanticTokenColors: semanticTokens(theme),
tokenColors: syntax(theme, hc, light),
};
- const outputPath = `${OUTPUT_DIR}/bearded-theme-${slug}.json`;
+ const outputPath = `${OUTPUT_DIR}/${Meta.slug}-${slug}.json`;
// Ensure directory exists
mkdirSync(dirname(outputPath), { recursive: true });
diff --git a/src/generators/zed/index.ts b/src/generators/zed/index.ts
index b9379ad..f4326bc 100644
--- a/src/generators/zed/index.ts
+++ b/src/generators/zed/index.ts
@@ -1,6 +1,7 @@
import { copyFileSync, mkdirSync, writeFileSync } from "fs";
import { join } from "path";
+import { Meta } from "../../shared/meta";
import {
getZedAppearance,
themeRegistry,
@@ -30,8 +31,8 @@ async function buildZedThemes(): Promise {
// Create the theme family with all themes
const themeFamily: ZedThemeFamily = {
$schema: "https://zed.dev/schema/themes/v0.2.0.json",
- author: "BeardedBear",
- name: "Bearded Theme",
+ author: Meta.author.name,
+ name: Meta.name,
themes: themeRegistry.map(createZedTheme),
};
@@ -43,13 +44,13 @@ async function buildZedThemes(): Promise {
);
// Generate extension.toml with synced version
- const extensionToml = `id = "bearded-theme"
-name = "Bearded Theme"
-description = "The theme with a long beard."
+ const extensionToml = `id = "${Meta.slug}"
+name = "${Meta.name}"
+description = "${Meta.description}"
version = "${version}"
schema_version = 1
-authors = ["BeardedBear "]
-repository = "https://github.com/BeardedBear/bearded-theme"
+authors = ["${Meta.author.name} <${Meta.author.email}>"]
+repository = "${Meta.urls.github}"
`;
writeFileSync(`${ZED_DIR}/extension.toml`, extensionToml, {
@@ -69,34 +70,34 @@ repository = "https://github.com/BeardedBear/bearded-theme"
}
// Generate README for Zed extension
- const readmeContent = `# Bearded Theme for Zed
+ const readmeContent = `# ${Meta.name} for Zed
-The theme with a long beard.
+${Meta.description}
## Installation
1. Open Zed
2. Open the Extensions panel (\`cmd+shift+x\` or \`ctrl+shift+x\`)
-3. Search for "Bearded Theme"
+3. Search for "${Meta.name}"
4. Click Install
## Available Themes
-${themeRegistry.map((entry) => `- Bearded Theme ${entry.name}`).join("\n")}
+${themeRegistry.map((entry) => `- ${Meta.name} ${entry.name}`).join("\n")}
## Links
-- [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=BeardedBear.beardedtheme)
-- [GitHub Repository](https://github.com/BeardedBear/bearded-theme)
-- [Report Issues](https://github.com/BeardedBear/bearded-theme/issues)
+- [VS Code Extension](${Meta.urls.marketplace.vscode})
+- [GitHub Repository](${Meta.urls.github})
+- [Report Issues](${Meta.urls.issues})
## License
-GNU General Public License v3.0
+${Meta.license}
## Author
-Made with ❤️ by [BeardedBear](https://github.com/BeardedBear)
+Made with ❤️ by [${Meta.author.name}](https://github.com/${Meta.author.name})
`;
writeFileSync(`${ZED_DIR}/README.md`, readmeContent, { encoding: "utf8" });
@@ -115,7 +116,7 @@ Made with ❤️ by [BeardedBear](https://github.com/BeardedBear)
function createZedTheme(entry: ThemeRegistryEntry): ZedTheme {
return {
appearance: getZedAppearance(entry.options),
- name: `Bearded Theme ${entry.name}`,
+ name: `${Meta.name} ${entry.name}`,
style: buildZedThemeStyle(entry.theme, entry.options),
};
}
diff --git a/src/shared/meta.ts b/src/shared/meta.ts
new file mode 100644
index 0000000..4972486
--- /dev/null
+++ b/src/shared/meta.ts
@@ -0,0 +1,68 @@
+
+export const Meta = {
+ name: "Bearded Theme",
+ slug: "bearded-theme",
+ description: "The theme with a long beard.",
+ author: {
+ name: "BeardedBear",
+ email: "beardedbearbear@gmail.com",
+ url: "https://github.com/BeardedBear/bearded-theme",
+ },
+ license: "GNU General Public License v3.0",
+ urls: {
+ github: "https://github.com/BeardedBear/bearded-theme",
+ issues: "https://github.com/BeardedBear/bearded-theme/issues",
+ marketplace: {
+ vscode:
+ "https://marketplace.visualstudio.com/items?itemName=BeardedBear.beardedtheme",
+ jetbrains: "https://plugins.jetbrains.com/plugin/19438-bearded-theme",
+ openVsx: "https://open-vsx.org/extension/BeardedBear/beardedtheme",
+ },
+ },
+ categories: [
+ {
+ name: "Arc",
+ description: "Clean, modern dark themes",
+ },
+ {
+ name: "Solarized",
+ description: "Classic solarized color schemes",
+ },
+ {
+ name: "Oceanic",
+ description: "Ocean-inspired color palettes",
+ },
+ {
+ name: "Monokai",
+ description: "Monokai-inspired variants",
+ },
+ {
+ name: "Black & Gems",
+ description: "Pure black backgrounds with gem accent colors",
+ },
+ {
+ name: "High Contrast (HC)",
+ description: "Accessibility-focused themes",
+ },
+ {
+ name: "Milkshake",
+ description: "Soft, pastel light themes",
+ },
+ {
+ name: "Coffee",
+ description: "Warm, earthy tones",
+ },
+ {
+ name: "Vivid",
+ description: "Vibrant, saturated colors",
+ },
+ {
+ name: "Aquarelle",
+ description: "Watercolor-inspired themes",
+ },
+ {
+ name: "Surprising",
+ description: "Unique, unexpected color combinations",
+ },
+ ],
+};
From cc10b53338b323f610be8dba104ae694f45bb38d Mon Sep 17 00:00:00 2001
From: BeardedBear
Date: Thu, 22 Jan 2026 00:00:01 +0100
Subject: [PATCH 9/9] Refactor Meta object ordering and formatting
Reorder fields in src/shared/meta.ts for a more consistent layout
(adjust author, categories and urls ordering) and tidy formatting.
Also fix indentation for join() calls in
src/generators/jetbrains/index.ts.
---
src/generators/jetbrains/index.ts | 4 +--
src/shared/meta.ts | 53 +++++++++++++++----------------
2 files changed, 28 insertions(+), 29 deletions(-)
diff --git a/src/generators/jetbrains/index.ts b/src/generators/jetbrains/index.ts
index 222259d..ddfc3c2 100644
--- a/src/generators/jetbrains/index.ts
+++ b/src/generators/jetbrains/index.ts
@@ -540,13 +540,13 @@ ${codeBlock}
## Available Themes
${themeRegistry.map((entry) => `- ${Meta.name} ${entry.name}`).join(
- "\n",
+ "\n",
)}
## Theme Categories
${Meta.categories.map((c) => `- **${c.name}** - ${c.description}`).join(
- "\n",
+ "\n",
)}
## Links
diff --git a/src/shared/meta.ts b/src/shared/meta.ts
index 4972486..4cd62ca 100644
--- a/src/shared/meta.ts
+++ b/src/shared/meta.ts
@@ -1,68 +1,67 @@
-
export const Meta = {
- name: "Bearded Theme",
- slug: "bearded-theme",
- description: "The theme with a long beard.",
author: {
- name: "BeardedBear",
email: "beardedbearbear@gmail.com",
+ name: "BeardedBear",
url: "https://github.com/BeardedBear/bearded-theme",
},
- license: "GNU General Public License v3.0",
- urls: {
- github: "https://github.com/BeardedBear/bearded-theme",
- issues: "https://github.com/BeardedBear/bearded-theme/issues",
- marketplace: {
- vscode:
- "https://marketplace.visualstudio.com/items?itemName=BeardedBear.beardedtheme",
- jetbrains: "https://plugins.jetbrains.com/plugin/19438-bearded-theme",
- openVsx: "https://open-vsx.org/extension/BeardedBear/beardedtheme",
- },
- },
categories: [
{
- name: "Arc",
description: "Clean, modern dark themes",
+ name: "Arc",
},
{
- name: "Solarized",
description: "Classic solarized color schemes",
+ name: "Solarized",
},
{
- name: "Oceanic",
description: "Ocean-inspired color palettes",
+ name: "Oceanic",
},
{
- name: "Monokai",
description: "Monokai-inspired variants",
+ name: "Monokai",
},
{
- name: "Black & Gems",
description: "Pure black backgrounds with gem accent colors",
+ name: "Black & Gems",
},
{
- name: "High Contrast (HC)",
description: "Accessibility-focused themes",
+ name: "High Contrast (HC)",
},
{
- name: "Milkshake",
description: "Soft, pastel light themes",
+ name: "Milkshake",
},
{
- name: "Coffee",
description: "Warm, earthy tones",
+ name: "Coffee",
},
{
- name: "Vivid",
description: "Vibrant, saturated colors",
+ name: "Vivid",
},
{
- name: "Aquarelle",
description: "Watercolor-inspired themes",
+ name: "Aquarelle",
},
{
- name: "Surprising",
description: "Unique, unexpected color combinations",
+ name: "Surprising",
},
],
+ description: "The theme with a long beard.",
+ license: "GNU General Public License v3.0",
+ name: "Bearded Theme",
+ slug: "bearded-theme",
+ urls: {
+ github: "https://github.com/BeardedBear/bearded-theme",
+ issues: "https://github.com/BeardedBear/bearded-theme/issues",
+ marketplace: {
+ jetbrains: "https://plugins.jetbrains.com/plugin/19438-bearded-theme",
+ openVsx: "https://open-vsx.org/extension/BeardedBear/beardedtheme",
+ vscode:
+ "https://marketplace.visualstudio.com/items?itemName=BeardedBear.beardedtheme",
+ },
+ },
};