diff --git a/scripts/publish.sh b/scripts/publish.sh index 20cd1420..dcaacbda 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -1,6 +1,7 @@ cargo publish -p yazi-macro && sleep 30 cargo publish -p yazi-codegen && sleep 30 cargo publish -p yazi-shared && sleep 30 +cargo publish -p yazi-ffi && sleep 30 cargo publish -p yazi-fs && sleep 30 cargo publish -p yazi-config && sleep 30 cargo publish -p yazi-proxy && sleep 30 diff --git a/yazi-adapter/src/adapter.rs b/yazi-adapter/src/adapter.rs index a3537ea7..3bce7cff 100644 --- a/yazi-adapter/src/adapter.rs +++ b/yazi-adapter/src/adapter.rs @@ -81,9 +81,9 @@ impl Adapter { impl Adapter { pub fn matches(emulator: Emulator) -> Self { - if matches!(emulator.kind.left(), Some(Brand::Microsoft)) { + if emulator.kind.is_left_and(|&b| b == Brand::Microsoft) { return Self::Sixel; - } else if *WSL && matches!(emulator.kind.left(), Some(Brand::WezTerm)) { + } else if WSL.get() && emulator.kind.is_left_and(|&b| b == Brand::WezTerm) { return Self::KgpOld; } @@ -92,7 +92,7 @@ impl Adapter { protocols.retain(|p| *p == Self::Iip); if env_exists("ZELLIJ_SESSION_NAME") { protocols.retain(|p| *p == Self::Sixel); - } else if *TMUX { + } else if TMUX.get() { protocols.retain(|p| *p != Self::KgpOld); } if let Some(p) = protocols.first() { diff --git a/yazi-adapter/src/brand.rs b/yazi-adapter/src/brand.rs index 712f6066..42d7b447 100644 --- a/yazi-adapter/src/brand.rs +++ b/yazi-adapter/src/brand.rs @@ -3,7 +3,7 @@ use yazi_shared::env_exists; use crate::{Mux, NVIM}; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Brand { Kitty, Konsole, @@ -19,6 +19,7 @@ pub enum Brand { Tabby, Hyper, Mintty, + Tmux, Neovim, Apple, Urxvt, @@ -26,10 +27,24 @@ pub enum Brand { } impl Brand { + pub(super) fn from_csi(resp: &str) -> Option { + let names = [ + ("kitty", Self::Kitty), + ("Konsole", Self::Konsole), + ("iTerm2", Self::Iterm2), + ("WezTerm", Self::WezTerm), + ("foot", Self::Foot), + ("ghostty", Self::Ghostty), + ("tmux ", Self::Tmux), + ("Bobcat", Self::Bobcat), + ]; + names.into_iter().find(|&(n, _)| resp.contains(n)).map(|(_, b)| b) + } + pub fn from_env() -> Option { use Brand as B; - if *NVIM { + if NVIM.get() { return Some(Self::Neovim); } @@ -76,19 +91,6 @@ impl Brand { None } - pub(super) fn from_csi(resp: &str) -> Option { - let names = [ - ("kitty", Self::Kitty), - ("Konsole", Self::Konsole), - ("iTerm2", Self::Iterm2), - ("WezTerm", Self::WezTerm), - ("foot", Self::Foot), - ("ghostty", Self::Ghostty), - ("Bobcat", Self::Bobcat), - ]; - names.into_iter().find(|&(n, _)| resp.contains(n)).map(|(_, b)| b) - } - pub(super) fn adapters(self) -> &'static [crate::Adapter] { use Brand as B; @@ -109,6 +111,7 @@ impl Brand { B::Tabby => &[A::Iip, A::Sixel], B::Hyper => &[A::Iip, A::Sixel], B::Mintty => &[A::Iip], + B::Tmux => &[], B::Neovim => &[], B::Apple => &[], B::Urxvt => &[], diff --git a/yazi-adapter/src/dimension.rs b/yazi-adapter/src/dimension.rs index 57d52037..673377e9 100644 --- a/yazi-adapter/src/dimension.rs +++ b/yazi-adapter/src/dimension.rs @@ -30,7 +30,8 @@ impl Dimension { pub fn ratio() -> Option<(f64, f64)> { let s = Self::available(); Some(if s.width == 0 || s.height == 0 { - (EMULATOR.cell_size?.0 as f64, EMULATOR.cell_size?.1 as f64) + let s = EMULATOR.get().cell_size?; + (s.0 as f64, s.1 as f64) } else { (f64::from(s.width) / f64::from(s.columns), f64::from(s.height) / f64::from(s.rows)) }) diff --git a/yazi-adapter/src/drivers/iip.rs b/yazi-adapter/src/drivers/iip.rs index 406570ac..967adc7c 100644 --- a/yazi-adapter/src/drivers/iip.rs +++ b/yazi-adapter/src/drivers/iip.rs @@ -53,14 +53,11 @@ impl Iip { write!( buf, - "{}]1337;File=inline=1;size={};width={}px;height={}px;doNotMoveCursor=1:", - START, + "{START}]1337;File=inline=1;size={};width={w}px;height={h}px;doNotMoveCursor=1:", b.len(), - w, - h, )?; STANDARD.encode_string(b, &mut buf); - write!(buf, "\x07{}", CLOSE)?; + write!(buf, "\x07{CLOSE}")?; Ok(buf.into_bytes()) }) diff --git a/yazi-adapter/src/drivers/kgp.rs b/yazi-adapter/src/drivers/kgp.rs index cbae32b8..051ca123 100644 --- a/yazi-adapter/src/drivers/kgp.rs +++ b/yazi-adapter/src/drivers/kgp.rs @@ -336,7 +336,7 @@ impl Kgp { write!(stderr, "{s}")?; } - write!(stderr, "{}_Gq=2,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?; + write!(stderr, "{START}_Gq=2,a=d,d=A{ESCAPE}\\{CLOSE}")?; Ok(()) }) } @@ -350,31 +350,21 @@ impl Kgp { if let Some(first) = it.next() { write!( buf, - "{}_Gq=2,a=T,i=1,C=1,U=1,f={},s={},v={},m={};{}{}\\{}", - START, - format, + "{START}_Gq=2,a=T,i=1,C=1,U=1,f={format},s={},v={},m={};{}{ESCAPE}\\{CLOSE}", size.0, size.1, it.peek().is_some() as u8, unsafe { str::from_utf8_unchecked(first) }, - ESCAPE, - CLOSE )?; } while let Some(chunk) = it.next() { - write!( - buf, - "{}_Gm={};{}{}\\{}", - START, - it.peek().is_some() as u8, - unsafe { str::from_utf8_unchecked(chunk) }, - ESCAPE, - CLOSE - )?; + write!(buf, "{START}_Gm={};{}{ESCAPE}\\{CLOSE}", it.peek().is_some() as u8, unsafe { + str::from_utf8_unchecked(chunk) + })?; } - write!(buf, "{}", CLOSE)?; + write!(buf, "{CLOSE}")?; Ok(buf) } diff --git a/yazi-adapter/src/drivers/kgp_old.rs b/yazi-adapter/src/drivers/kgp_old.rs index 86c88159..1d5259f7 100644 --- a/yazi-adapter/src/drivers/kgp_old.rs +++ b/yazi-adapter/src/drivers/kgp_old.rs @@ -27,7 +27,7 @@ impl KgpOld { #[inline] pub(crate) fn image_erase(_: Rect) -> Result<()> { let mut stderr = LineWriter::new(stderr()); - write!(stderr, "{}_Gq=2,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?; + write!(stderr, "{START}_Gq=2,a=d,d=A{ESCAPE}\\{CLOSE}")?; stderr.flush()?; Ok(()) } @@ -41,31 +41,21 @@ impl KgpOld { if let Some(first) = it.next() { write!( buf, - "{}_Gq=2,a=T,z=-1,C=1,f={},s={},v={},m={};{}{}\\{}", - START, - format, + "{START}_Gq=2,a=T,z=-1,C=1,f={format},s={},v={},m={};{}{ESCAPE}\\{CLOSE}", size.0, size.1, it.peek().is_some() as u8, unsafe { str::from_utf8_unchecked(first) }, - ESCAPE, - CLOSE )?; } while let Some(chunk) = it.next() { - write!( - buf, - "{}_Gm={};{}{}\\{}", - START, - it.peek().is_some() as u8, - unsafe { str::from_utf8_unchecked(chunk) }, - ESCAPE, - CLOSE - )?; + write!(buf, "{START}_Gm={};{}{ESCAPE}\\{CLOSE}", it.peek().is_some() as u8, unsafe { + str::from_utf8_unchecked(chunk) + })?; } - write!(buf, "{}", CLOSE)?; + write!(buf, "{CLOSE}")?; Ok(buf) } diff --git a/yazi-adapter/src/drivers/sixel.rs b/yazi-adapter/src/drivers/sixel.rs index 859fea38..56a30993 100644 --- a/yazi-adapter/src/drivers/sixel.rs +++ b/yazi-adapter/src/drivers/sixel.rs @@ -47,7 +47,7 @@ impl Sixel { let nq = NeuQuant::new(PREVIEW.sixel_fraction as i32, 256 - alpha as usize, &img); let mut buf: Vec = Vec::with_capacity(1 << 16); - write!(buf, "{}P0;1;8q\"1;1;{};{}", START, img.width(), img.height())?; + write!(buf, "{START}P0;1;8q\"1;1;{};{}", img.width(), img.height())?; // Palette for (i, c) in nq.color_map_rgba().chunks(4).enumerate() { @@ -96,7 +96,7 @@ impl Sixel { } } - write!(buf, "{}\\{}", ESCAPE, CLOSE)?; + write!(buf, "{ESCAPE}\\{CLOSE}")?; Ok(buf) }) .await? diff --git a/yazi-adapter/src/emulator.rs b/yazi-adapter/src/emulator.rs index b2e3e3d1..ce9ba642 100644 --- a/yazi-adapter/src/emulator.rs +++ b/yazi-adapter/src/emulator.rs @@ -17,40 +17,37 @@ pub struct Emulator { } impl Default for Emulator { - fn default() -> Self { - Self { kind: Either::Right(Unknown::default()), light: false, cell_size: None } - } + fn default() -> Self { Self::unknown() } } impl Emulator { - pub fn detect() -> Self { - if let Some(brand) = Brand::from_env() { - Self { kind: Either::Left(brand), ..Self::detect_base().unwrap_or_default() } - } else { - Self::detect_full().unwrap_or_default() - } - } - - pub fn detect_full() -> Result { + pub fn detect() -> Result { defer! { disable_raw_mode().ok(); } enable_raw_mode()?; + let resort = Brand::from_env(); + let kgp_seq = if resort.is_none() { + Mux::csi("\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\") + } else { + "".into() + }; + execute!( LineWriter::new(stderr()), SavePosition, - Print(Mux::csi("\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\")), // Detect KGP - Print(Mux::csi("\x1b[>q")), // Request terminal version - Print("\x1b[16t"), // Request cell size - Print("\x1b]11;?\x07"), // Request background color - Print(Mux::csi("\x1b[0c")), // Request device attributes + Print(kgp_seq), // Detect KGP + Print(Mux::csi("\x1b[>q")), // Request terminal version + Print("\x1b[16t"), // Request cell size + Print("\x1b]11;?\x07"), // Request background color + Print(Mux::csi("\x1b[0c")), // Request device attributes RestorePosition )?; let resp = futures::executor::block_on(Self::read_until_da1()); Mux::tmux_drain()?; - let kind = if let Some(brand) = Brand::from_csi(&resp) { - Either::Left(brand) + let kind = if let Some(b) = Brand::from_csi(&resp).or(resort) { + Either::Left(b) } else { Either::Right(Unknown { kgp: resp.contains("\x1b_Gi=31;OK"), @@ -65,6 +62,10 @@ impl Emulator { }) } + pub const fn unknown() -> Self { + Self { kind: Either::Right(Unknown::default()), light: false, cell_size: None } + } + pub fn adapters(self) -> &'static [Adapter] { match self.kind { Either::Left(brand) => brand.adapters(), @@ -84,7 +85,7 @@ impl Emulator { // I really don't want to add this, // But tmux and ConPTY sometimes cause the cursor position to get out of sync. - if *TMUX || cfg!(windows) { + if TMUX.get() || cfg!(windows) { execute!(buf, SavePosition, MoveTo(x, y), Show)?; execute!(buf, MoveTo(x, y), Show)?; execute!(buf, MoveTo(x, y), Show)?; @@ -94,7 +95,7 @@ impl Emulator { } let result = cb(&mut buf); - if *TMUX || cfg!(windows) { + if TMUX.get() || cfg!(windows) { queue!(buf, Hide, RestorePosition)?; } else { queue!(buf, RestorePosition)?; @@ -194,27 +195,6 @@ impl Emulator { Ok(()) } - fn detect_base() -> Result { - defer! { disable_raw_mode().ok(); } - enable_raw_mode()?; - - execute!( - LineWriter::new(stderr()), - Print("\x1b[16t"), // Request cell size - Print("\x1b]11;?\x07"), // Request background color - Print("\x1b[0c"), // Request device attributes - )?; - - let resp = futures::executor::block_on(Self::read_until_da1()); - Mux::tmux_drain()?; - - Ok(Self { - light: Self::light_bg(&resp).unwrap_or_default(), - cell_size: Self::cell_size(&resp), - ..Default::default() - }) - } - fn cell_size(resp: &str) -> Option<(u16, u16)> { let b = resp.split_once("\x1b[6;")?.1.as_bytes(); diff --git a/yazi-adapter/src/lib.rs b/yazi-adapter/src/lib.rs index f05a96e6..c05ddd45 100644 --- a/yazi-adapter/src/lib.rs +++ b/yazi-adapter/src/lib.rs @@ -4,48 +4,49 @@ yazi_macro::mod_pub!(drivers); yazi_macro::mod_flat!(adapter brand dimension emulator image info mux unknown); -use yazi_shared::{RoCell, SyncCell, env_exists, in_wsl}; +use yazi_shared::{SyncCell, env_exists, in_wsl}; -pub static EMULATOR: RoCell = RoCell::new(); -pub static ADAPTOR: RoCell = RoCell::new(); +pub static EMULATOR: SyncCell = SyncCell::new(Emulator::unknown()); +pub static ADAPTOR: SyncCell = SyncCell::new(Adapter::Chafa); // Image state static SHOWN: SyncCell> = SyncCell::new(None); -// Tmux support -pub static TMUX: RoCell = RoCell::new(); -static ESCAPE: RoCell<&'static str> = RoCell::new(); -static START: RoCell<&'static str> = RoCell::new(); -static CLOSE: RoCell<&'static str> = RoCell::new(); - // WSL support -pub static WSL: RoCell = RoCell::new(); +pub static WSL: SyncCell = SyncCell::new(false); // Neovim support -pub static NVIM: RoCell = RoCell::new(); +pub static NVIM: SyncCell = SyncCell::new(false); + +// Tmux support +pub static TMUX: SyncCell = SyncCell::new(false); +static ESCAPE: SyncCell<&'static str> = SyncCell::new("\x1b"); +static START: SyncCell<&'static str> = SyncCell::new("\x1b"); +static CLOSE: SyncCell<&'static str> = SyncCell::new(""); pub fn init() -> anyhow::Result<()> { - init_default(); - - EMULATOR.init(Emulator::detect()); - yazi_config::init_flavor(EMULATOR.light)?; - - ADAPTOR.init(Adapter::matches(*EMULATOR)); - ADAPTOR.start(); - - Ok(()) -} - -pub fn init_default() { - // Tmux support - TMUX.init(Mux::tmux_passthrough()); - ESCAPE.init(if *TMUX { "\x1b\x1b" } else { "\x1b" }); - START.init(if *TMUX { "\x1bPtmux;\x1b\x1b" } else { "\x1b" }); - CLOSE.init(if *TMUX { "\x1b\\" } else { "" }); - // WSL support - WSL.init(in_wsl()); + WSL.set(in_wsl()); // Neovim support - NVIM.init(env_exists("NVIM_LOG_FILE") && env_exists("NVIM")); + NVIM.set(env_exists("NVIM_LOG_FILE") && env_exists("NVIM")); + + // Emulator detection + EMULATOR.set(Emulator::detect().unwrap_or_default()); + TMUX.set(EMULATOR.get().kind.is_left_and(|&b| b == Brand::Tmux)); + + // Tmux support + if TMUX.get() { + ESCAPE.set("\x1b\x1b"); + START.set("\x1bPtmux;\x1b\x1b"); + CLOSE.set("\x1b\\"); + Mux::tmux_passthrough(); + EMULATOR.set(Emulator::detect().unwrap_or_default()); + } + + yazi_config::init_flavor(EMULATOR.get().light)?; + + ADAPTOR.set(Adapter::matches(EMULATOR.get())); + ADAPTOR.get().start(); + Ok(()) } diff --git a/yazi-adapter/src/mux.rs b/yazi-adapter/src/mux.rs index f4493f91..c358057a 100644 --- a/yazi-adapter/src/mux.rs +++ b/yazi-adapter/src/mux.rs @@ -7,25 +7,17 @@ pub struct Mux; impl Mux { pub fn csi(s: &str) -> std::borrow::Cow { - if *TMUX && !*NVIM { + if TMUX.get() && !NVIM.get() { std::borrow::Cow::Owned(format!( - "{}{}{}", - *START, - s.trim_start_matches('\x1b').replace('\x1b', *ESCAPE), - *CLOSE + "{START}{}{CLOSE}", + s.trim_start_matches('\x1b').replace('\x1b', ESCAPE.get()), )) } else { std::borrow::Cow::Borrowed(s) } } - pub fn tmux_passthrough() -> bool { - if !std::env::var("TERM_PROGRAM").is_ok_and(|s| s == "tmux") - && !std::env::var("TERM").is_ok_and(|s| s.starts_with("tmux")) - { - return false; - } - + pub fn tmux_passthrough() { let child = std::process::Command::new("tmux") .args(["set", "-p", "allow-passthrough", "on"]) .stdin(std::process::Stdio::null()) @@ -46,11 +38,10 @@ impl Mux { error!("Failed to spawn `tmux set -p allow-passthrough on`: {e}"); } } - true } pub fn tmux_drain() -> Result<()> { - if *TMUX && !*NVIM { + if TMUX.get() && !NVIM.get() { crossterm::execute!(std::io::stderr(), crossterm::style::Print(Mux::csi("\x1b[5n")))?; _ = futures::executor::block_on(Emulator::read_until_dsr()); } @@ -74,7 +65,7 @@ impl Mux { pub(super) fn term_program() -> (Option, Option) { let (mut term, mut program) = (None, None); - if !*TMUX { + if !TMUX.get() { return (term, program); } let Ok(output) = std::process::Command::new("tmux").arg("show-environment").output() else { diff --git a/yazi-adapter/src/unknown.rs b/yazi-adapter/src/unknown.rs index 0a4dd18d..1c21f301 100644 --- a/yazi-adapter/src/unknown.rs +++ b/yazi-adapter/src/unknown.rs @@ -1,12 +1,14 @@ use crate::Adapter; -#[derive(Debug, Clone, Copy, Default)] +#[derive(Debug, Clone, Copy)] pub struct Unknown { pub kgp: bool, pub sixel: bool, } impl Unknown { + pub(super) const fn default() -> Self { Self { kgp: false, sixel: false } } + pub(super) fn adapters(self) -> &'static [Adapter] { use Adapter as A; diff --git a/yazi-boot/src/actions/debug.rs b/yazi-boot/src/actions/debug.rs index 93f64d72..6115d924 100644 --- a/yazi-boot/src/actions/debug.rs +++ b/yazi-boot/src/actions/debug.rs @@ -17,14 +17,13 @@ impl Actions { writeln!(s, "\nYa")?; writeln!(s, " Version: {}", Self::process_output("ya", "--version"))?; - let emulator = yazi_adapter::Emulator::detect(); + let emulator = yazi_adapter::Emulator::detect().unwrap_or_default(); writeln!(s, "\nEmulator")?; writeln!(s, " TERM : {:?}", env::var_os("TERM"))?; writeln!(s, " TERM_PROGRAM : {:?}", env::var_os("TERM_PROGRAM"))?; writeln!(s, " TERM_PROGRAM_VERSION: {:?}", env::var_os("TERM_PROGRAM_VERSION"))?; writeln!(s, " Brand.from_env : {:?}", yazi_adapter::Brand::from_env())?; writeln!(s, " Emulator.detect : {:?}", emulator)?; - writeln!(s, " Emulator.detect_full: {:?}", yazi_adapter::Emulator::detect_full())?; writeln!(s, "\nAdapter")?; writeln!(s, " Adapter.matches: {:?}", yazi_adapter::Adapter::matches(emulator))?; @@ -42,10 +41,10 @@ impl Actions { writeln!(s, " shared.in_ssh_connection: {:?}", yazi_shared::in_ssh_connection())?; writeln!(s, "\nWSL")?; - writeln!(s, " WSL: {:?}", *yazi_adapter::WSL)?; + writeln!(s, " WSL: {:?}", yazi_adapter::WSL.get())?; writeln!(s, "\nNeovim")?; - writeln!(s, " NVIM : {}", *yazi_adapter::NVIM)?; + writeln!(s, " NVIM : {}", yazi_adapter::NVIM.get())?; writeln!(s, " Neovim version: {}", Self::process_output("nvim", "--version"))?; writeln!(s, "\nVariables")?; @@ -75,7 +74,7 @@ impl Actions { )?; writeln!(s, "\nMultiplexers")?; - writeln!(s, " TMUX : {}", *yazi_adapter::TMUX)?; + writeln!(s, " TMUX : {}", yazi_adapter::TMUX.get())?; writeln!(s, " tmux version : {}", Self::process_output("tmux", "-V"))?; writeln!(s, " tmux build flags : enable-sixel={}", Mux::tmux_sixel_flag())?; writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?; diff --git a/yazi-config/preset/README.md b/yazi-config/preset/README.md index a2982e4f..a1528d90 100644 --- a/yazi-config/preset/README.md +++ b/yazi-config/preset/README.md @@ -16,13 +16,13 @@ However, if you want to customize certain configurations: - Create a `yazi.toml` in your config directory to override certain settings in [`yazi-default.toml`][yazi-default], so either: - `~/.config/yazi/yazi.toml` on Unix-like systems - - `C:\Users\USERNAME\AppData\Roaming\yazi\config\yazi.toml` on Windows + - `%AppData%\yazi\config\yazi.toml` on Windows - Create a `keymap.toml` in your config directory to override certain settings in [`keymap-default.toml`][keymap-default], so either: - `~/.config/yazi/keymap.toml` on Unix-like systems - - `C:\Users\USERNAME\AppData\Roaming\yazi\config\keymap.toml` on Windows + - `%AppData%\yazi\config\keymap.toml` on Windows - Create a `theme.toml` in your config directory to override certain settings in [`theme-light.toml`][theme-light] and [`theme-dark.toml`][theme-dark], so either: - `~/.config/yazi/theme.toml` on Unix-like systems - - `C:\Users\USERNAME\AppData\Roaming\yazi\config\theme.toml` on Windows + - `%AppData%\yazi\config\theme.toml` on Windows For the user's `theme.toml` file, you can only apply the same color scheme to both the light and dark themes. diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index 9b84d823..6afc46d9 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -36,7 +36,7 @@ impl Watcher { }; let config = notify::Config::default().with_poll_interval(Duration::from_millis(500)); - if *yazi_adapter::WSL { + if yazi_adapter::WSL.get() { tokio::spawn(Self::fan_in(in_rx, PollWatcher::new(handler, config).unwrap())); } else { tokio::spawn(Self::fan_in(in_rx, RecommendedWatcher::new(handler, config).unwrap())); diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs index dd900219..97f070ac 100644 --- a/yazi-core/src/tab/preview.rs +++ b/yazi-core/src/tab/preview.rs @@ -70,14 +70,14 @@ impl Preview { #[inline] pub fn reset(&mut self) { self.abort(); - ADAPTOR.image_hide().ok(); + ADAPTOR.get().image_hide().ok(); render!(self.lock.take().is_some()) } #[inline] pub fn reset_image(&mut self) { self.abort(); - ADAPTOR.image_hide().ok(); + ADAPTOR.get().image_hide().ok(); } #[inline] diff --git a/yazi-fm/src/term.rs b/yazi-fm/src/term.rs index 8c808415..3d390850 100644 --- a/yazi-fm/src/term.rs +++ b/yazi-fm/src/term.rs @@ -26,7 +26,7 @@ impl Term { }; enable_raw_mode()?; - if *yazi_adapter::TMUX { + if yazi_adapter::TMUX.get() { yazi_adapter::Mux::tmux_passthrough(); } @@ -268,12 +268,12 @@ mod screen { impl crossterm::Command for SetScreen { fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result { - if self.0 == *TMUX { Ok(()) } else { EnterAlternateScreen.write_ansi(f) } + if self.0 == TMUX.get() { Ok(()) } else { EnterAlternateScreen.write_ansi(f) } } #[cfg(windows)] fn execute_winapi(&self) -> std::io::Result<()> { - if self.0 == *TMUX { Ok(()) } else { EnterAlternateScreen.execute_winapi() } + if self.0 == TMUX.get() { Ok(()) } else { EnterAlternateScreen.execute_winapi() } } #[cfg(windows)] diff --git a/yazi-plugin/preset/plugins/extract.lua b/yazi-plugin/preset/plugins/extract.lua index e2517078..329c87d7 100644 --- a/yazi-plugin/preset/plugins/extract.lua +++ b/yazi-plugin/preset/plugins/extract.lua @@ -6,7 +6,7 @@ function M:setup() ps.sub_remote("extract", function(args) local noisy = #args == 1 and ' "" --noisy' or ' ""' for _, arg in ipairs(args) do - ya.manager_emit("plugin", { self._id, args = ya.quote(arg, true) .. noisy }) + ya.manager_emit("plugin", { self._id, ya.quote(arg, true) .. noisy }) end end) end diff --git a/yazi-plugin/src/elements/clear.rs b/yazi-plugin/src/elements/clear.rs index f7eec593..6a3feba1 100644 --- a/yazi-plugin/src/elements/clear.rs +++ b/yazi-plugin/src/elements/clear.rs @@ -38,11 +38,11 @@ impl ratatui::widgets::Widget for Clear { { ratatui::widgets::Clear.render(area, buf); - let Some(r) = ADAPTOR.shown_load().and_then(|r| overlap(area, r)) else { + let Some(r) = ADAPTOR.get().shown_load().and_then(|r| overlap(area, r)) else { return; }; - ADAPTOR.image_erase(r).ok(); + ADAPTOR.get().image_erase(r).ok(); COLLISION.store(true, Ordering::Relaxed); for y in r.top()..r.bottom() { for x in r.left()..r.right() { diff --git a/yazi-plugin/src/utils/image.rs b/yazi-plugin/src/utils/image.rs index 4b80dc59..0e8ada59 100644 --- a/yazi-plugin/src/utils/image.rs +++ b/yazi-plugin/src/utils/image.rs @@ -17,7 +17,7 @@ impl Utils { pub(super) fn image_show(lua: &Lua) -> mlua::Result { lua.create_async_function(|lua, (url, rect): (UrlRef, Rect)| async move { - if let Ok(area) = ADAPTOR.image_show(&url, *rect).await { + if let Ok(area) = ADAPTOR.get().image_show(&url, *rect).await { Rect::from(area).into_lua(&lua) } else { Value::Nil.into_lua(&lua) diff --git a/yazi-shared/src/either.rs b/yazi-shared/src/either.rs index 1a6a3e58..dfa6e6e9 100644 --- a/yazi-shared/src/either.rs +++ b/yazi-shared/src/either.rs @@ -33,6 +33,14 @@ impl Either { } } + pub fn is_left_and bool>(&self, f: F) -> bool { + self.left().map(f).unwrap_or(false) + } + + pub fn is_right_and bool>(&self, f: F) -> bool { + self.right().map(f).unwrap_or(false) + } + pub fn into_left(self) -> Option { match self { Either::Left(l) => Some(l), diff --git a/yazi-shared/src/sync_cell.rs b/yazi-shared/src/sync_cell.rs index 7e15d095..f7fa6552 100644 --- a/yazi-shared/src/sync_cell.rs +++ b/yazi-shared/src/sync_cell.rs @@ -1,4 +1,4 @@ -use std::{cell::Cell, fmt::{Debug, Formatter}, ops::Deref}; +use std::{cell::Cell, fmt::{Debug, Display, Formatter}, ops::Deref}; /// [`SyncCell`], but [`Sync`]. /// @@ -34,3 +34,7 @@ impl Debug for SyncCell { f.debug_struct("SyncCell").field("value", &self.get()).finish() } } + +impl Display for SyncCell { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.get(), f) } +}