Skip to content

Commit

Permalink
fix: reverse the order of CSI-based and environment-based terminal de…
Browse files Browse the repository at this point in the history
…tection (#2310)
  • Loading branch information
sxyazi authored Feb 9, 2025
1 parent 17ff1e8 commit 793c90f
Show file tree
Hide file tree
Showing 22 changed files with 132 additions and 165 deletions.
1 change: 1 addition & 0 deletions scripts/publish.sh
Original file line number Diff line number Diff line change
@@ -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
Expand Down
6 changes: 3 additions & 3 deletions yazi-adapter/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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() {
Expand Down
33 changes: 18 additions & 15 deletions yazi-adapter/src/brand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -19,17 +19,32 @@ pub enum Brand {
Tabby,
Hyper,
Mintty,
Tmux,
Neovim,
Apple,
Urxvt,
Bobcat,
}

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);
}

Expand Down Expand Up @@ -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;

Expand All @@ -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 => &[],
Expand Down
3 changes: 2 additions & 1 deletion yazi-adapter/src/dimension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
Expand Down
7 changes: 2 additions & 5 deletions yazi-adapter/src/drivers/iip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
})
Expand Down
22 changes: 6 additions & 16 deletions yazi-adapter/src/drivers/kgp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
})
}
Expand All @@ -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)
}

Expand Down
22 changes: 6 additions & 16 deletions yazi-adapter/src/drivers/kgp_old.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand All @@ -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)
}

Expand Down
4 changes: 2 additions & 2 deletions yazi-adapter/src/drivers/sixel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -96,7 +96,7 @@ impl Sixel {
}
}

write!(buf, "{}\\{}", ESCAPE, CLOSE)?;
write!(buf, "{ESCAPE}\\{CLOSE}")?;
Ok(buf)
})
.await?
Expand Down
64 changes: 22 additions & 42 deletions yazi-adapter/src/emulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand All @@ -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(),
Expand All @@ -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)?;
Expand All @@ -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)?;
Expand Down Expand Up @@ -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();

Expand Down
Loading

0 comments on commit 793c90f

Please sign in to comment.