From 577065cbd05a282a1d6f923c89cdf74d5af2f3e9 Mon Sep 17 00:00:00 2001 From: Zane Weissman Date: Tue, 11 Nov 2025 23:41:13 -0500 Subject: [PATCH] feat: new `overall` option to set the overall background color (#3317) --- CHANGELOG.md | 2 ++ yazi-config/preset/theme-dark.toml | 8 ++++++++ yazi-config/preset/theme-light.toml | 8 ++++++++ yazi-config/src/color.rs | 16 +++++++++++----- yazi-config/src/style.rs | 2 -- yazi-config/src/theme/theme.rs | 10 ++++++++++ yazi-fm/src/term.rs | 4 +++- yazi-plugin/src/theme/theme.rs | 16 ++++++++++++++++ yazi-term/src/background.rs | 16 ++++++++++++++++ yazi-term/src/lib.rs | 2 +- 10 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 yazi-term/src/background.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 17f4eb36..28c2366d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/): - Zoom in or out of the preview image ([#2864]) - Improve the UX of the pick and input components ([#2906], [#2935]) - Show progress of each task in task manager ([#3121], [#3131], [#3134]) +- New `overall` option to set the overall background color ([#3317]) - New `bulk_rename` command always renames files with the editor ([#2984]) - `key-*` DDS events to allow changing or canceling user key events ([#3005], [#3037]) - New `--bg` specifying image background color in the preset SVG and ImageMagick previewers ([#3189]) @@ -1535,3 +1536,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/): [#3286]: https://github.com/sxyazi/yazi/pull/3286 [#3290]: https://github.com/sxyazi/yazi/pull/3290 [#3313]: https://github.com/sxyazi/yazi/pull/3313 +[#3317]: https://github.com/sxyazi/yazi/pull/3317 diff --git a/yazi-config/preset/theme-dark.toml b/yazi-config/preset/theme-dark.toml index 1fcf2dc7..d4bb9230 100644 --- a/yazi-config/preset/theme-dark.toml +++ b/yazi-config/preset/theme-dark.toml @@ -16,6 +16,14 @@ light = "" # : }}} +# : App {{{ + +[app] +overall = {} + +# : }}} + + # : Manager {{{ [mgr] diff --git a/yazi-config/preset/theme-light.toml b/yazi-config/preset/theme-light.toml index 88e9a6f9..8bd2c90e 100644 --- a/yazi-config/preset/theme-light.toml +++ b/yazi-config/preset/theme-light.toml @@ -16,6 +16,14 @@ light = "" # : }}} +# : App {{{ + +[app] +overall = {} + +# : }}} + + # : Manager {{{ [mgr] diff --git a/yazi-config/src/color.rs b/yazi-config/src/color.rs index fbdbe23b..bf0b63ba 100644 --- a/yazi-config/src/color.rs +++ b/yazi-config/src/color.rs @@ -1,10 +1,20 @@ -use std::str::FromStr; +use std::{ops::Deref, str::FromStr}; use serde::Deserialize; #[derive(Clone, Copy, Debug, Default)] pub struct Color(ratatui::style::Color); +impl Deref for Color { + type Target = ratatui::style::Color; + + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl From for ratatui::style::Color { + fn from(value: Color) -> Self { value.0 } +} + impl<'de> Deserialize<'de> for Color { fn deserialize(deserializer: D) -> Result where @@ -15,7 +25,3 @@ impl<'de> Deserialize<'de> for Color { .map(Self) } } - -impl From for ratatui::style::Color { - fn from(value: Color) -> Self { value.0 } -} diff --git a/yazi-config/src/style.rs b/yazi-config/src/style.rs index 46602ba4..e2531bb0 100644 --- a/yazi-config/src/style.rs +++ b/yazi-config/src/style.rs @@ -5,9 +5,7 @@ use crate::Color; #[derive(Clone, Copy, Debug, Default, Deserialize)] pub struct Style { - #[serde(default)] pub fg: Option, - #[serde(default)] pub bg: Option, #[serde(default)] pub bold: bool, diff --git a/yazi-config/src/theme/theme.rs b/yazi-config/src/theme/theme.rs index b3a8369f..b607dbb7 100644 --- a/yazi-config/src/theme/theme.rs +++ b/yazi-config/src/theme/theme.rs @@ -12,6 +12,7 @@ use crate::Style; #[derive(Deserialize, DeserializeOver1)] pub struct Theme { pub flavor: Flavor, + pub app: App, pub mgr: Mgr, pub tabs: Tabs, pub mode: Mode, @@ -33,6 +34,11 @@ pub struct Theme { pub icon: Icon, } +#[derive(Deserialize, DeserializeOver2)] +pub struct App { + pub overall: Style, +} + #[derive(Deserialize, DeserializeOver2)] pub struct Mgr { pub cwd: Style, @@ -229,3 +235,7 @@ impl Theme { Ok(self) } } + +impl App { + pub fn bg_color(&self) -> String { self.overall.bg.map(|c| c.to_string()).unwrap_or_default() } +} diff --git a/yazi-fm/src/term.rs b/yazi-fm/src/term.rs index d6426d0b..c3bf1c19 100644 --- a/yazi-fm/src/term.rs +++ b/yazi-fm/src/term.rs @@ -4,7 +4,7 @@ use anyhow::Result; use crossterm::{event::{DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, style::Print, terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle, disable_raw_mode, enable_raw_mode}}; use ratatui::{CompletedFrame, Frame, Terminal, backend::CrosstermBackend, buffer::Buffer, layout::Rect}; use yazi_adapter::{Emulator, Mux, TMUX}; -use yazi_config::YAZI; +use yazi_config::{THEME, YAZI}; use yazi_shared::SyncCell; use yazi_term::tty::{TTY, TtyWriter}; @@ -38,6 +38,7 @@ impl Term { Print("\x1b[?u"), // Request keyboard enhancement flags (CSI u) Print("\x1b[0c"), // Request device attributes yazi_term::If(TMUX.get(), EnterAlternateScreen), + yazi_term::SetBackground(true, THEME.app.bg_color()), // Set app background EnableBracketedPaste, yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), EnableMouseCapture), )?; @@ -100,6 +101,7 @@ impl Term { execute!( TTY.writer(), yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), DisableMouseCapture), + yazi_term::SetBackground(false, THEME.app.bg_color()), yazi_term::RestoreCursor, DisableBracketedPaste, LeaveAlternateScreen, diff --git a/yazi-plugin/src/theme/theme.rs b/yazi-plugin/src/theme/theme.rs index 5b8f6d81..dfc5c8d0 100644 --- a/yazi-plugin/src/theme/theme.rs +++ b/yazi-plugin/src/theme/theme.rs @@ -5,6 +5,7 @@ use yazi_config::THEME; pub fn compose() -> Composer { fn get(lua: &Lua, key: &[u8]) -> mlua::Result { match key { + b"app" => app(), b"mgr" => mgr(), b"tabs" => tabs(), b"mode" => mode(), @@ -28,6 +29,21 @@ pub fn compose() -> Composer { Composer::new(get, set) } +fn app() -> Composer { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let a = &THEME.app; + match key { + b"overall" => Style::from(a.overall).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::new(get, set) +} + fn mgr() -> Composer { fn get(lua: &Lua, key: &[u8]) -> mlua::Result { let m = &THEME.mgr; diff --git a/yazi-term/src/background.rs b/yazi-term/src/background.rs new file mode 100644 index 00000000..de20c482 --- /dev/null +++ b/yazi-term/src/background.rs @@ -0,0 +1,16 @@ +pub struct SetBackground(pub bool, pub String); + +impl crossterm::Command for SetBackground { + fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result { + if self.1.is_empty() { + return Ok(()); + } else if self.0 { + write!(f, "\x1b]11;{}\x1b\\", self.1) + } else { + write!(f, "\x1b]111\x1b\\") + } + } + + #[cfg(windows)] + fn execute_winapi(&self) -> std::io::Result<()> { Ok(()) } +} diff --git a/yazi-term/src/lib.rs b/yazi-term/src/lib.rs index 351a0497..c743409c 100644 --- a/yazi-term/src/lib.rs +++ b/yazi-term/src/lib.rs @@ -2,6 +2,6 @@ yazi_macro::mod_pub!(tty); -yazi_macro::mod_flat!(cursor r#if); +yazi_macro::mod_flat!(background cursor r#if); pub fn init() { tty::init(); }