mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
fix: reverse the order of CSI-based and environment-based terminal detection (#2310)
This commit is contained in:
parent
17ff1e8812
commit
793c90f021
22 changed files with 133 additions and 166 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<Self> {
|
||||
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<Self> {
|
||||
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<Self> {
|
||||
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 => &[],
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ impl Sixel {
|
|||
let nq = NeuQuant::new(PREVIEW.sixel_fraction as i32, 256 - alpha as usize, &img);
|
||||
|
||||
let mut buf: Vec<u8> = 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?
|
||||
|
|
|
|||
|
|
@ -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<Self> {
|
||||
pub fn detect() -> Result<Self> {
|
||||
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<Self> {
|
||||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Emulator> = RoCell::new();
|
||||
pub static ADAPTOR: RoCell<Adapter> = RoCell::new();
|
||||
pub static EMULATOR: SyncCell<Emulator> = SyncCell::new(Emulator::unknown());
|
||||
pub static ADAPTOR: SyncCell<Adapter> = SyncCell::new(Adapter::Chafa);
|
||||
|
||||
// Image state
|
||||
static SHOWN: SyncCell<Option<ratatui::layout::Rect>> = SyncCell::new(None);
|
||||
|
||||
// Tmux support
|
||||
pub static TMUX: RoCell<bool> = 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<bool> = RoCell::new();
|
||||
pub static WSL: SyncCell<bool> = SyncCell::new(false);
|
||||
|
||||
// Neovim support
|
||||
pub static NVIM: RoCell<bool> = RoCell::new();
|
||||
pub static NVIM: SyncCell<bool> = SyncCell::new(false);
|
||||
|
||||
// Tmux support
|
||||
pub static TMUX: SyncCell<bool> = 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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,25 +7,17 @@ pub struct Mux;
|
|||
|
||||
impl Mux {
|
||||
pub fn csi(s: &str) -> std::borrow::Cow<str> {
|
||||
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<String>, Option<String>) {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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"))?;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ impl Utils {
|
|||
|
||||
pub(super) fn image_show(lua: &Lua) -> mlua::Result<Function> {
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,14 @@ impl<L, R> Either<L, R> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_left_and<F: FnOnce(&L) -> bool>(&self, f: F) -> bool {
|
||||
self.left().map(f).unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn is_right_and<F: FnOnce(&R) -> bool>(&self, f: F) -> bool {
|
||||
self.right().map(f).unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn into_left(self) -> Option<L> {
|
||||
match self {
|
||||
Either::Left(l) => Some(l),
|
||||
|
|
|
|||
|
|
@ -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<T: Copy + Debug> Debug for SyncCell<T> {
|
|||
f.debug_struct("SyncCell").field("value", &self.get()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Display> Display for SyncCell<T> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.get(), f) }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue