From 97cda23556057a9b326eb0de38ac1d44e59f2777 Mon Sep 17 00:00:00 2001 From: Bjarne Oeverli Date: Tue, 21 Oct 2025 08:10:04 +0200 Subject: [PATCH] Add a zed template, and copy to the zed themes --- src/components/SettingsSidebar.js | 24 +++ src/utils/ConfigWriter.js | 50 ++++- src/utils/service-manager.js | 48 +++++ templates/aether.zed.json | 302 ++++++++++++++++++++++++++++++ 4 files changed, 423 insertions(+), 1 deletion(-) create mode 100644 templates/aether.zed.json diff --git a/src/components/SettingsSidebar.js b/src/components/SettingsSidebar.js index 54b5e6a..53316b4 100644 --- a/src/components/SettingsSidebar.js +++ b/src/components/SettingsSidebar.js @@ -51,6 +51,7 @@ export const SettingsSidebar = GObject.registerClass( // Default values this._includeNeovim = true; this._includeVencord = false; + this._includeZed = false; this._includeGtk = false; this._lightMode = false; this._selectedNeovimConfig = null; @@ -617,6 +618,26 @@ export const SettingsSidebar = GObject.registerClass( expanderRow.add_row(vencordRow); + const zedRow = new Adw.ActionRow({ + title: 'Include Zed Theme', + subtitle: 'Copy aether.zed.json to ~/.config/zed/themes/', + }); + + this._zedSwitch = new Gtk.Switch({ + active: this._includeZed, + valign: Gtk.Align.CENTER, + }); + + this._zedSwitch.connect('notify::active', sw => { + this._includeZed = sw.get_active(); + this.emit('settings-changed', this.getSettings()); + }); + + zedRow.add_suffix(this._zedSwitch); + zedRow.set_activatable_widget(this._zedSwitch); + + expanderRow.add_row(zedRow); + return expanderRow; } @@ -768,6 +789,7 @@ export const SettingsSidebar = GObject.registerClass( return { includeNeovim: this._includeNeovim, includeVencord: this._includeVencord, + includeZed: this._includeZed, includeGtk: this._includeGtk, lightMode: this._lightMode, selectedNeovimConfig: this._selectedNeovimConfig, @@ -786,6 +808,7 @@ export const SettingsSidebar = GObject.registerClass( if (settings) { this._includeNeovim = settings.includeNeovim ?? true; this._includeVencord = settings.includeVencord ?? false; + this._includeZed = settings.includeZed ?? false; this._includeGtk = settings.includeGtk ?? false; this._enableAppOverrides = settings.enableAppOverrides ?? false; console.log('Loaded settings from', this._settingsPath); @@ -802,6 +825,7 @@ export const SettingsSidebar = GObject.registerClass( const settings = { includeNeovim: this._includeNeovim, includeVencord: this._includeVencord, + includeZed: this._includeZed, includeGtk: this._includeGtk, enableAppOverrides: this._enableAppOverrides, }; diff --git a/src/utils/ConfigWriter.js b/src/utils/ConfigWriter.js index 6112026..90e7ad4 100644 --- a/src/utils/ConfigWriter.js +++ b/src/utils/ConfigWriter.js @@ -11,7 +11,11 @@ import { createSymlink, } from './file-utils.js'; import {hexToRgbString, hexToRgba, hexToYaruTheme} from './color-utils.js'; -import {restartSwaybg, copyVencordTheme} from './service-manager.js'; +import { + restartSwaybg, + copyVencordTheme, + copyZedTheme, +} from './service-manager.js'; import {DEFAULT_COLORS} from '../constants/colors.js'; import {getAppNameFromFileName} from '../constants/templates.js'; @@ -68,6 +72,11 @@ export class ConfigWriter { this._copyVencordTheme(); } + // Copy Zed theme if enabled + if (settings.includeZed === true) { + this._copyZedTheme(); + } + this._handleLightModeMarker(this.themeDir, lightMode); this._applyOmarchyTheme(); @@ -129,6 +138,14 @@ export class ConfigWriter { return; } + // Skip aether.zed.json if includeZed is false + if ( + fileName === 'aether.zed.json' && + settings.includeZed === false + ) { + return; + } + // Skip gtk.css if includeGtk is false if (fileName === 'gtk.css' && settings.includeGtk === false) { return; @@ -330,6 +347,14 @@ export class ConfigWriter { return; } + // Skip aether.zed.json if includeZed is false + if ( + fileName === 'aether.zed.json' && + settings.includeZed === false + ) { + return; + } + // Skip gtk.css if includeGtk is false if (fileName === 'gtk.css' && settings.includeGtk === false) { return; @@ -517,6 +542,29 @@ export class ConfigWriter { } } + _copyZedTheme() { + try { + const zedSourcePath = GLib.build_filenamev([ + this.themeDir, + 'aether.zed.json', + ]); + + // Check if source file exists + const sourceFile = Gio.File.new_for_path(zedSourcePath); + if (!sourceFile.query_exists(null)) { + console.log( + 'aether.zed.json not found in theme directory, skipping Zed copy' + ); + return; + } + + // Copy to ~/.config/zed/themes/ + copyZedTheme(zedSourcePath); + } catch (e) { + console.error('Error copying Zed theme:', e.message); + } + } + _copyGtkFile(sourcePath, destPath, label) { try { // Remove existing file if it exists diff --git a/src/utils/service-manager.js b/src/utils/service-manager.js index bae26db..8829a84 100644 --- a/src/utils/service-manager.js +++ b/src/utils/service-manager.js @@ -119,3 +119,51 @@ export function copyVencordTheme(sourcePath) { return successCount; } + +/** + * Copies Zed theme to ~/.config/zed/themes/ + * @param {string} sourcePath - Path to the aether.zed.json file + * @returns {boolean} Success status + */ +export function copyZedTheme(sourcePath) { + // Validate source path + if (!sourcePath) { + console.error('copyZedTheme: sourcePath is required'); + return false; + } + + const sourceFile = Gio.File.new_for_path(sourcePath); + if (!sourceFile.query_exists(null)) { + console.error(`copyZedTheme: Source file not found: ${sourcePath}`); + return false; + } + + const configDir = GLib.get_user_config_dir(); + const OUTPUT_FILENAME = 'aether.json'; + + try { + const zedThemesPath = GLib.build_filenamev([ + configDir, + 'zed', + 'themes', + ]); + + // Ensure the themes directory exists + ensureDirectoryExists(zedThemesPath); + + // Copy the theme file + const destPath = GLib.build_filenamev([zedThemesPath, OUTPUT_FILENAME]); + const success = copyFile(sourcePath, destPath); + + if (success) { + console.log(`Copied Zed theme to: ${destPath}`); + return true; + } else { + console.error(`Failed to copy Zed theme to: ${destPath}`); + return false; + } + } catch (e) { + console.error(`Error copying Zed theme:`, e.message); + return false; + } +} diff --git a/templates/aether.zed.json b/templates/aether.zed.json new file mode 100644 index 0000000..adacd89 --- /dev/null +++ b/templates/aether.zed.json @@ -0,0 +1,302 @@ +{ + "$schema": "https://zed.dev/schema/themes/v0.1.0.json", + "name": "aether", + "author": "Aether", + "themes": [ + { + "name": "Aether", + "appearance": "dark", + "style": { + "border": "{color0}", + "border.variant": "{color0}", + "border.focused": null, + "border.selected": null, + "border.transparent": null, + "border.disabled": null, + "elevated_surface.background": "{background}", + "surface.background": "{background}", + "background": "{background}", + "element.background": "{color8}", + "element.hover": "{color0}", + "element.active": null, + "element.selected": "{color0}", + "element.disabled": null, + "drop_target.background": "{color0}", + "ghost_element.background": null, + "ghost_element.hover": "{color8}", + "ghost_element.active": null, + "ghost_element.selected": "{color0}", + "ghost_element.disabled": null, + "text": "{foreground}", + "text.muted": "{color7}", + "text.placeholder": "{color7}", + "text.disabled": "{color0}", + "text.accent": "{color6}", + "icon": null, + "icon.muted": null, + "icon.disabled": null, + "icon.placeholder": null, + "icon.accent": null, + "status_bar.background": "{background}", + "title_bar.background": "{background}", + "title_bar.inactive_background": "{color8}", + "toolbar.background": "{background}", + "tab_bar.background": "{background}", + "tab.inactive_background": "{color8}", + "tab.active_background": "{background}", + "search.match_background": "{color0}", + "panel.background": "{background}", + "panel.focused_border": "{color0}", + "pane.focused_border": null, + "scrollbar.thumb.background": "{color0}", + "scrollbar.thumb.hover_background": "{color8}", + "scrollbar.thumb.border": "{color0}6f", + "scrollbar.track.background": "{background}", + "scrollbar.track.border": null, + "editor.foreground": "{foreground}", + "editor.background": "{background}", + "editor.gutter.background": "{background}", + "editor.subheader.background": "{background}", + "editor.active_line.background": "{color8}", + "editor.highlighted_line.background": null, + "editor.line_number": "{color8}", + "editor.active_line_number": "{color15}", + "editor.invisible": null, + "editor.wrap_guide": "{color8}", + "editor.active_wrap_guide": "{color8}", + "editor.document_highlight.read_background": "{color8}", + "editor.document_highlight.write_background": "{color8}", + "terminal.background": "{background}", + "terminal.foreground": null, + "terminal.bright_foreground": null, + "terminal.dim_foreground": null, + "terminal.ansi.black": "{background}", + "terminal.ansi.bright_black": "{color8}", + "terminal.ansi.dim_black": null, + "terminal.ansi.red": "{color1}", + "terminal.ansi.bright_red": "{color1}", + "terminal.ansi.dim_red": null, + "terminal.ansi.green": "{color2}", + "terminal.ansi.bright_green": "{color2}", + "terminal.ansi.dim_green": null, + "terminal.ansi.yellow": "{color3}", + "terminal.ansi.bright_yellow": "{color3}", + "terminal.ansi.dim_yellow": null, + "terminal.ansi.blue": "{color4}", + "terminal.ansi.bright_blue": "{color4}", + "terminal.ansi.dim_blue": null, + "terminal.ansi.magenta": "{color5}", + "terminal.ansi.bright_magenta": "{color5}", + "terminal.ansi.dim_magenta": null, + "terminal.ansi.cyan": "{color6}", + "terminal.ansi.bright_cyan": "{color6}", + "terminal.ansi.dim_cyan": null, + "terminal.ansi.white": "{foreground}", + "terminal.ansi.bright_white": "{color7}", + "terminal.ansi.dim_white": null, + "link_text.hover": "{color6}", + "conflict": "{color3}", + "conflict.background": "{background}", + "conflict.border": "{color3}", + "created": "{color2}", + "created.background": "{background}", + "created.border": "{color2}", + "deleted": "{color1}", + "deleted.background": "{background}", + "deleted.border": "{color1}", + "error": "{color1}", + "error.background": "{background}", + "error.border": "{color1}", + "hidden": "{color8}", + "hidden.background": "{background}", + "hidden.border": "{color8}", + "hint": "{foreground}", + "hint.background": "{background}", + "hint.border": "{color6}", + "ignored": "{color8}", + "ignored.background": "{background}", + "ignored.border": "{color8}", + "info": "{color6}", + "info.background": "{background}", + "info.border": "{color6}", + "modified": "{color4}", + "modified.background": "{background}", + "modified.border": "{color4}", + "predictive": "{color8}", + "predictive.background": "{color8}", + "predictive.border": "{color0}", + "renamed": "{color3}", + "renamed.background": "{background}", + "renamed.border": "{color3}", + "success": "{color2}", + "success.background": "{background}", + "success.border": "{color2}", + "unreachable": "{color3}", + "unreachable.background": "{background}", + "unreachable.border": "{color3}", + "warning": "{color3}", + "warning.background": "{background}", + "warning.border": "{color3}", + "players": [ + { + "cursor": "{foreground}", + "selection": "{color0}", + "background": null + } + ], + "syntax": { + "attribute": { + "color": "{color4}", + "font_style": null, + "font_weight": null + }, + "boolean": { + "color": "{color9}", + "font_style": null, + "font_weight": null + }, + "comment": { + "color": "{color8}", + "font_style": "italic", + "font_weight": null + }, + "comment.doc": { + "color": "{color8}", + "font_style": "italic", + "font_weight": null + }, + "constant": { + "color": "{color9}", + "font_style": null, + "font_weight": null + }, + "constructor": { + "color": "{color1}", + "font_style": null, + "font_weight": null + }, + "emphasis": { + "color": "{color1}", + "font_style": "italic", + "font_weight": null + }, + "emphasis.strong": { + "color": "{color1}", + "font_style": null, + "font_weight": 700 + }, + "function": { + "color": "{color4}", + "font_style": null, + "font_weight": null + }, + "keyword": { + "color": "{color5}", + "font_style": null, + "font_weight": null + }, + "label": { + "color": "{color3}", + "font_style": null, + "font_weight": null + }, + "link_text": { + "color": "{color1}", + "font_style": null, + "font_weight": null + }, + "link_uri": { + "color": "{color1}", + "font_style": null, + "font_weight": null + }, + "number": { + "color": "{color9}", + "font_style": null, + "font_weight": null + }, + "punctuation": { + "color": "{foreground}", + "font_style": null, + "font_weight": null + }, + "punctuation.bracket": { + "color": "{foreground}", + "font_style": null, + "font_weight": null + }, + "punctuation.delimiter": { + "color": "{foreground}", + "font_style": null, + "font_weight": null + }, + "punctuation.list_marker": { + "color": "{foreground}", + "font_style": null, + "font_weight": null + }, + "punctuation.special": { + "color": "{foreground}", + "font_style": null, + "font_weight": null + }, + "string": { + "color": "{color2}", + "font_style": null, + "font_weight": null + }, + "string.escape": { + "color": "{color9}", + "font_style": null, + "font_weight": null + }, + "string.regex": { + "color": "{color2}", + "font_style": null, + "font_weight": null + }, + "string.special": { + "color": "{color2}", + "font_style": null, + "font_weight": null + }, + "string.special.symbol": { + "color": "{color2}", + "font_style": null, + "font_weight": null + }, + "tag": { + "color": "{color1}", + "font_style": null, + "font_weight": null + }, + "text.literal": { + "color": "{color2}", + "font_style": null, + "font_weight": null + }, + "title": { + "color": "{color3}", + "font_style": null, + "font_weight": null + }, + "type": { + "color": "{color3}", + "font_style": null, + "font_weight": null + }, + "variable": { + "color": "{color1}", + "font_style": null, + "font_weight": null + }, + "variable.special": { + "color": "{color1}", + "font_style": "italic", + "font_weight": null + } + } + } + } + ] +}