diff --git a/docs/next/CHANGELOG.md b/docs/next/CHANGELOG.md index 9bbdfc192b..cad470a91f 100644 --- a/docs/next/CHANGELOG.md +++ b/docs/next/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +### Added +- Custom themes can now define separate light and dark color overrides when automatic theme switching is enabled. (#837, thanks @aneym) + ### Fixed - Retained mouse selections now copy when Ctrl+C or Cmd+C arrives before a delayed mouse release instead of forwarding the copy shortcut to the pane. (#3100, thanks @moret) - Removing a background worktree workspace no longer changes focus to its parent workspace. (#3098) diff --git a/docs/next/website/src/content/docs/configuration.mdx b/docs/next/website/src/content/docs/configuration.mdx index 5d4a7ab105..222a5d6863 100644 --- a/docs/next/website/src/content/docs/configuration.mdx +++ b/docs/next/website/src/content/docs/configuration.mdx @@ -277,6 +277,23 @@ yellow = "#f9e2af" Color values accept hex, named colors, `rgb(r,g,b)`, or reset aliases like `reset`, `default`, `none`, and `transparent`. +When `auto_switch` is enabled, optional light and dark subtables layer on top of the shared custom colors: + +```toml +[theme.custom] +accent = "#89b4fa" + +[theme.custom.light] +panel_bg = "#eff1f5" +text = "#4c4f69" + +[theme.custom.dark] +panel_bg = "#1e1e2e" +text = "#cdd6f4" +``` + +The active palette is applied in this order: built-in theme, `[theme.custom]`, then `[theme.custom.light]` or `[theme.custom.dark]`. Omitting the mode subtables preserves the existing shared override behavior. + ## UI and sidebar The sidebar is the main Herdr dashboard. Search `ui.` in the [Config reference](/docs/config-reference/) for sizing, collapsed mode, Agent panel ordering, mouse behavior, pane borders, and other presentation settings. diff --git a/docs/next/website/src/content/docs/ja/configuration.mdx b/docs/next/website/src/content/docs/ja/configuration.mdx index e93c20bde0..b2af36c80c 100644 --- a/docs/next/website/src/content/docs/ja/configuration.mdx +++ b/docs/next/website/src/content/docs/ja/configuration.mdx @@ -273,6 +273,23 @@ yellow = "#f9e2af" 色の値には、hex、名前付きの色、`rgb(r,g,b)`、または `reset`、`default`、`none`、`transparent` のようなリセットエイリアスが使えます。 +`auto_switch` が有効な場合は、ライト/ダーク別のサブテーブルを共有カスタム色の上に重ねられます: + +```toml +[theme.custom] +accent = "#89b4fa" + +[theme.custom.light] +panel_bg = "#eff1f5" +text = "#4c4f69" + +[theme.custom.dark] +panel_bg = "#1e1e2e" +text = "#cdd6f4" +``` + +有効なパレットには、組み込みテーマ、`[theme.custom]`、`[theme.custom.light]` または `[theme.custom.dark]` の順で適用されます。モード別のサブテーブルを省略すると、既存の共有上書きの挙動が維持されます。 + ## UI とサイドバー サイドバーは Herdr のメインダッシュボードです。サイズ、折りたたみモード、Agent パネルの並び順、マウスの挙動、ペインの境界線、その他の表示設定については、[設定リファレンス](/docs/config-reference/)で `ui.` を検索してください。 diff --git a/docs/next/website/src/content/docs/zh-cn/configuration.mdx b/docs/next/website/src/content/docs/zh-cn/configuration.mdx index 97a923a08f..46db877711 100644 --- a/docs/next/website/src/content/docs/zh-cn/configuration.mdx +++ b/docs/next/website/src/content/docs/zh-cn/configuration.mdx @@ -273,6 +273,23 @@ yellow = "#f9e2af" 颜色值支持十六进制、命名颜色、`rgb(r,g,b)`,以及 `reset`、`default`、`none`、`transparent` 等重置别名。 +启用 `auto_switch` 后,可以通过明暗模式子表在共享自定义颜色之上应用不同的覆盖值: + +```toml +[theme.custom] +accent = "#89b4fa" + +[theme.custom.light] +panel_bg = "#eff1f5" +text = "#4c4f69" + +[theme.custom.dark] +panel_bg = "#1e1e2e" +text = "#cdd6f4" +``` + +有效调色板按以下顺序应用:内置主题、`[theme.custom]`,然后是 `[theme.custom.light]` 或 `[theme.custom.dark]`。省略模式子表时,会保留现有的共享覆盖行为。 + ## UI 与侧边栏 侧边栏是 Herdr 的主仪表盘。在[配置参考](/docs/config-reference/)中搜索 `ui.`,可查看尺寸、折叠模式、Agent 面板排序、鼠标行为、窗格边框和其他显示设置。 diff --git a/docs/next/website/src/data/config-reference.json b/docs/next/website/src/data/config-reference.json index 1765c10fb1..147d705618 100644 --- a/docs/next/website/src/data/config-reference.json +++ b/docs/next/website/src/data/config-reference.json @@ -171,6 +171,234 @@ "type": "color", "default": "unset", "description": "Override the peach color token on top of the base theme. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.accent", + "type": "color", + "default": "unset", + "description": "Override the accent color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.panel_bg", + "type": "color", + "default": "unset", + "description": "Override the panel_bg color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.sidebar_bg", + "type": "color", + "default": "unset", + "description": "Override the sidebar_bg color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.active_row_bg", + "type": "color", + "default": "unset", + "description": "Override the active_row_bg color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.selection_bg", + "type": "color", + "default": "unset", + "description": "Override the selection_bg color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.surface0", + "type": "color", + "default": "unset", + "description": "Override the surface0 color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.surface1", + "type": "color", + "default": "unset", + "description": "Override the surface1 color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.surface_dim", + "type": "color", + "default": "unset", + "description": "Override the surface_dim color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.overlay0", + "type": "color", + "default": "unset", + "description": "Override the overlay0 color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.overlay1", + "type": "color", + "default": "unset", + "description": "Override the overlay1 color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.text", + "type": "color", + "default": "unset", + "description": "Override the text color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.subtext0", + "type": "color", + "default": "unset", + "description": "Override the subtext0 color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.mauve", + "type": "color", + "default": "unset", + "description": "Override the mauve color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.green", + "type": "color", + "default": "unset", + "description": "Override the green color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.yellow", + "type": "color", + "default": "unset", + "description": "Override the yellow color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.red", + "type": "color", + "default": "unset", + "description": "Override the red color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.blue", + "type": "color", + "default": "unset", + "description": "Override the blue color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.teal", + "type": "color", + "default": "unset", + "description": "Override the teal color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.light.peach", + "type": "color", + "default": "unset", + "description": "Override the peach color token when auto_switch selects a light appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.accent", + "type": "color", + "default": "unset", + "description": "Override the accent color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.panel_bg", + "type": "color", + "default": "unset", + "description": "Override the panel_bg color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.sidebar_bg", + "type": "color", + "default": "unset", + "description": "Override the sidebar_bg color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.active_row_bg", + "type": "color", + "default": "unset", + "description": "Override the active_row_bg color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.selection_bg", + "type": "color", + "default": "unset", + "description": "Override the selection_bg color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.surface0", + "type": "color", + "default": "unset", + "description": "Override the surface0 color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.surface1", + "type": "color", + "default": "unset", + "description": "Override the surface1 color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.surface_dim", + "type": "color", + "default": "unset", + "description": "Override the surface_dim color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.overlay0", + "type": "color", + "default": "unset", + "description": "Override the overlay0 color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.overlay1", + "type": "color", + "default": "unset", + "description": "Override the overlay1 color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.text", + "type": "color", + "default": "unset", + "description": "Override the text color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.subtext0", + "type": "color", + "default": "unset", + "description": "Override the subtext0 color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.mauve", + "type": "color", + "default": "unset", + "description": "Override the mauve color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.green", + "type": "color", + "default": "unset", + "description": "Override the green color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.yellow", + "type": "color", + "default": "unset", + "description": "Override the yellow color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.red", + "type": "color", + "default": "unset", + "description": "Override the red color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.blue", + "type": "color", + "default": "unset", + "description": "Override the blue color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.teal", + "type": "color", + "default": "unset", + "description": "Override the teal color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." + }, + { + "key": "theme.custom.dark.peach", + "type": "color", + "default": "unset", + "description": "Override the peach color token when auto_switch selects a dark appearance. Applied after theme.custom. Accepts hex, named colors, rgb(r,g,b), or reset aliases." } ] }, diff --git a/src/app/mod.rs b/src/app/mod.rs index 85ad4fa35e..ff286c3f18 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -337,6 +337,7 @@ fn resolve_palette_for_theme_name( name: &str, fallback_name: &str, runtime: &state::ThemeRuntimeConfig, + mode_custom: Option<&crate::config::ModeThemeColors>, ) -> state::Palette { let mut palette = state::Palette::from_name(name).unwrap_or_else(|| { tracing::warn!( @@ -353,6 +354,9 @@ fn resolve_palette_for_theme_name( if let Some(accent) = &runtime.legacy_accent { palette.accent = crate::config::parse_color(accent); } + if let Some(custom) = mode_custom { + palette = palette.with_mode_overrides(custom); + } palette } @@ -361,18 +365,30 @@ fn resolve_effective_theme( runtime: &state::ThemeRuntimeConfig, appearance: Option, ) -> (state::Palette, String) { - let (name, fallback) = if runtime.auto_switch { + let (name, fallback, mode_custom) = if runtime.auto_switch { match appearance.unwrap_or(crate::terminal_theme::HostAppearance::Dark) { - crate::terminal_theme::HostAppearance::Dark => (&runtime.dark_name, "catppuccin"), - crate::terminal_theme::HostAppearance::Light => { - (&runtime.light_name, "catppuccin-latte") - } + crate::terminal_theme::HostAppearance::Dark => ( + &runtime.dark_name, + "catppuccin", + runtime + .custom + .as_ref() + .and_then(|custom| custom.dark.as_ref()), + ), + crate::terminal_theme::HostAppearance::Light => ( + &runtime.light_name, + "catppuccin-latte", + runtime + .custom + .as_ref() + .and_then(|custom| custom.light.as_ref()), + ), } } else { - (&runtime.manual_name, "catppuccin") + (&runtime.manual_name, "catppuccin", None) }; ( - resolve_palette_for_theme_name(name, fallback, runtime), + resolve_palette_for_theme_name(name, fallback, runtime, mode_custom), name.clone(), ) } @@ -2807,6 +2823,17 @@ mod tests { fn theme_auto_switch_is_opt_in_and_preserves_manual_default() { let mut config = Config::default(); config.theme.name = Some("tokyo-night".to_string()); + config.theme.custom = Some(crate::config::CustomThemeColors { + light: Some(crate::config::ModeThemeColors { + accent: Some("#010203".to_string()), + ..Default::default() + }), + dark: Some(crate::config::ModeThemeColors { + accent: Some("#040506".to_string()), + ..Default::default() + }), + ..Default::default() + }); let (_api_tx, api_rx) = tokio::sync::mpsc::unbounded_channel(); let app = App::new(&config, true, None, api_rx, crate::api::EventHub::default()); @@ -2854,6 +2881,55 @@ mod tests { ); } + #[test] + fn theme_auto_switch_layers_active_mode_overrides_last() { + let mut config = Config::default(); + config.theme.name = Some("gruvbox".to_string()); + config.theme.auto_switch = true; + config.theme.custom = Some(crate::config::CustomThemeColors { + accent: Some("#010203".to_string()), + text: Some("#040506".to_string()), + light: Some(crate::config::ModeThemeColors { + accent: Some("#070809".to_string()), + ..Default::default() + }), + dark: Some(crate::config::ModeThemeColors { + text: Some("#0a0b0c".to_string()), + sidebar_bg: Some("#0d0e0f".to_string()), + active_row_bg: Some("#101112".to_string()), + ..Default::default() + }), + ..Default::default() + }); + let (_api_tx, api_rx) = tokio::sync::mpsc::unbounded_channel(); + let mut app = App::new(&config, true, None, api_rx, crate::api::EventHub::default()); + + assert_eq!( + app.state.palette.accent, + ratatui::style::Color::Rgb(1, 2, 3) + ); + assert_eq!( + app.state.palette.text, + ratatui::style::Color::Rgb(10, 11, 12) + ); + assert_eq!( + app.state.palette.sidebar_bg, + ratatui::style::Color::Rgb(13, 14, 15) + ); + assert_eq!( + app.state.palette.active_row_bg, + ratatui::style::Color::Rgb(16, 17, 18) + ); + + app.set_host_terminal_appearance(crate::terminal_theme::HostAppearance::Light, true); + + assert_eq!( + app.state.palette.accent, + ratatui::style::Color::Rgb(7, 8, 9) + ); + assert_eq!(app.state.palette.text, ratatui::style::Color::Rgb(4, 5, 6)); + } + #[test] fn inferred_background_appearance_does_not_override_explicit_report() { let mut config = Config::default(); diff --git a/src/app/state.rs b/src/app/state.rs index d9dcfc9dfb..21ee889902 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -645,6 +645,68 @@ impl Palette { } self } + + pub fn with_mode_overrides(mut self, custom: &crate::config::ModeThemeColors) -> Self { + use crate::config::parse_color; + if let Some(c) = &custom.accent { + self.accent = parse_color(c); + } + if let Some(c) = &custom.panel_bg { + self.panel_bg = parse_color(c); + } + if let Some(c) = &custom.sidebar_bg { + self.sidebar_bg = parse_color(c); + } + if let Some(c) = &custom.active_row_bg { + self.active_row_bg = parse_color(c); + } + if let Some(c) = &custom.selection_bg { + self.selection_bg = parse_color(c); + } + if let Some(c) = &custom.surface0 { + self.surface0 = parse_color(c); + } + if let Some(c) = &custom.surface1 { + self.surface1 = parse_color(c); + } + if let Some(c) = &custom.surface_dim { + self.surface_dim = parse_color(c); + } + if let Some(c) = &custom.overlay0 { + self.overlay0 = parse_color(c); + } + if let Some(c) = &custom.overlay1 { + self.overlay1 = parse_color(c); + } + if let Some(c) = &custom.text { + self.text = parse_color(c); + } + if let Some(c) = &custom.subtext0 { + self.subtext0 = parse_color(c); + } + if let Some(c) = &custom.mauve { + self.mauve = parse_color(c); + } + if let Some(c) = &custom.green { + self.green = parse_color(c); + } + if let Some(c) = &custom.yellow { + self.yellow = parse_color(c); + } + if let Some(c) = &custom.red { + self.red = parse_color(c); + } + if let Some(c) = &custom.blue { + self.blue = parse_color(c); + } + if let Some(c) = &custom.teal { + self.teal = parse_color(c); + } + if let Some(c) = &custom.peach { + self.peach = parse_color(c); + } + self + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/config.rs b/src/config.rs index 0595ae2f76..02ad2fbc6b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,7 +33,7 @@ pub use self::{ }, sound::SoundConfig, tab_bar::TabBarRightEntryConfig, - theme::{parse_color, CustomThemeColors, ThemeConfig, THEME_NAMES}, + theme::{parse_color, CustomThemeColors, ModeThemeColors, ThemeConfig, THEME_NAMES}, window_title::{WindowTitlePart, WindowTitleTemplate, WindowTitleToken}, }; diff --git a/src/config/theme.rs b/src/config/theme.rs index 8f28390c7f..cb9e34986e 100644 --- a/src/config/theme.rs +++ b/src/config/theme.rs @@ -119,6 +119,35 @@ pub struct CustomThemeColors { pub blue: Option, pub teal: Option, pub peach: Option, + /// Overrides applied when `auto_switch` selects a light appearance. + pub light: Option, + /// Overrides applied when `auto_switch` selects a dark appearance. + pub dark: Option, +} + +/// Per-token color overrides for one auto-switch appearance. +#[derive(Debug, Clone, Default, Deserialize)] +#[serde(default)] +pub struct ModeThemeColors { + pub accent: Option, + pub panel_bg: Option, + pub sidebar_bg: Option, + pub active_row_bg: Option, + pub selection_bg: Option, + pub surface0: Option, + pub surface1: Option, + pub surface_dim: Option, + pub overlay0: Option, + pub overlay1: Option, + pub text: Option, + pub subtext0: Option, + pub mauve: Option, + pub green: Option, + pub yellow: Option, + pub red: Option, + pub blue: Option, + pub teal: Option, + pub peach: Option, } /// Parse a color string into a ratatui Color. @@ -283,6 +312,35 @@ red = "rgb(255, 85, 85)" assert!(custom.green.is_none()); } + #[test] + fn theme_custom_mode_overrides_parse() { + let toml = r##" +[theme.custom] +accent = "#010203" + +[theme.custom.light] +accent = "#040506" +text = "#070809" +selection_bg = "#101112" + +[theme.custom.dark] +panel_bg = "#0a0b0c" +sidebar_bg = "#0d0e0f" +active_row_bg = "#131415" +"##; + let config: Config = toml::from_str(toml).unwrap(); + let custom = config.theme.custom.as_ref().unwrap(); + assert_eq!(custom.accent.as_deref(), Some("#010203")); + let light = custom.light.as_ref().unwrap(); + assert_eq!(light.accent.as_deref(), Some("#040506")); + assert_eq!(light.text.as_deref(), Some("#070809")); + assert_eq!(light.selection_bg.as_deref(), Some("#101112")); + let dark = custom.dark.as_ref().unwrap(); + assert_eq!(dark.panel_bg.as_deref(), Some("#0a0b0c")); + assert_eq!(dark.sidebar_bg.as_deref(), Some("#0d0e0f")); + assert_eq!(dark.active_row_bg.as_deref(), Some("#131415")); + } + #[test] fn theme_defaults_when_missing() { let config: Config = toml::from_str("").unwrap(); diff --git a/src/main.rs b/src/main.rs index 56dbb8df26..a6ba1c0309 100644 --- a/src/main.rs +++ b/src/main.rs @@ -137,6 +137,15 @@ const DEFAULT_CONFIG: &str = r##"# herdr configuration # red = "#ff6188" # green = "#a6e3a1" +# Layer appearance-specific overrides on top when auto_switch is enabled. +# [theme.custom.light] +# panel_bg = "#eff1f5" +# text = "#4c4f69" +# +# [theme.custom.dark] +# panel_bg = "#1e1e2e" +# text = "#cdd6f4" + [terminal] # Executable used for new interactive panes. # Empty means $SHELL, then /bin/sh.