mirror of
https://github.com/sxyazi/yazi.git
synced 2024-12-28 19:24:06 +03:00
feat: detect CSI u through Stderr
to allow using Stdout
as the carrier of DDS payload without an ANSI sequence response timeout (#867)
This commit is contained in:
parent
b51babde1c
commit
ec83c5dc5c
588
Cargo.lock
generated
588
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -14,15 +14,16 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.81"
|
||||
arc-swap = "1.7.0"
|
||||
arc-swap = "1.7.1"
|
||||
base64 = "0.22.0"
|
||||
color_quant = "1.1.0"
|
||||
crossterm = "0.27.0"
|
||||
image = "0.24.9"
|
||||
futures = "0.3.30"
|
||||
image = "0.25.1"
|
||||
imagesize = "0.12.0"
|
||||
kamadak-exif = "0.5.5"
|
||||
ratatui = "0.26.1"
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
|
||||
# Logging
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
|
@ -1,9 +1,9 @@
|
||||
use std::{env, io::{stderr, LineWriter, Read}};
|
||||
use std::{env, io::{stderr, LineWriter}};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use crossterm::{cursor::{RestorePosition, SavePosition}, execute, style::Print, terminal::{disable_raw_mode, enable_raw_mode}};
|
||||
use tracing::warn;
|
||||
use yazi_shared::env_exists;
|
||||
use yazi_shared::{env_exists, term::Term};
|
||||
|
||||
use crate::{Adaptor, TMUX};
|
||||
|
||||
@ -120,20 +120,9 @@ impl Emulator {
|
||||
RestorePosition
|
||||
)?;
|
||||
|
||||
let mut stdin = std::io::stdin().lock();
|
||||
let mut buf = String::with_capacity(200);
|
||||
loop {
|
||||
let mut c = [0; 1];
|
||||
if stdin.read(&mut c)? == 0 {
|
||||
break;
|
||||
}
|
||||
if c[0] == b'c' && buf.contains("\x1b[?") {
|
||||
break;
|
||||
}
|
||||
buf.push(c[0] as char);
|
||||
}
|
||||
|
||||
let resp = futures::executor::block_on(Term::read_until_da1())?;
|
||||
disable_raw_mode().ok();
|
||||
|
||||
let names = [
|
||||
("kitty", Self::Kitty),
|
||||
("Konsole", Self::Konsole),
|
||||
@ -144,16 +133,16 @@ impl Emulator {
|
||||
];
|
||||
|
||||
for (name, emulator) in names.iter() {
|
||||
if buf.contains(name) {
|
||||
if resp.contains(name) {
|
||||
return Ok(emulator.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let mut adapters = Vec::with_capacity(2);
|
||||
if buf.contains("\x1b_Gi=31;OK") {
|
||||
if resp.contains("\x1b_Gi=31;OK") {
|
||||
adapters.push(Adaptor::KittyOld);
|
||||
}
|
||||
if ["?4;", "?4c", ";4;", ";4c"].iter().any(|s| buf.contains(s)) {
|
||||
if ["?4;", "?4c", ";4;", ";4c"].iter().any(|s| resp.contains(s)) {
|
||||
adapters.push(Adaptor::Sixel);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ impl Image {
|
||||
img.as_bytes(),
|
||||
img.width(),
|
||||
img.height(),
|
||||
img.color(),
|
||||
img.color().into(),
|
||||
)?;
|
||||
Ok::<_, anyhow::Error>(buf)
|
||||
})
|
||||
|
@ -14,11 +14,11 @@ yazi-config = { path = "../yazi-config", version = "0.2.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.2.4" }
|
||||
|
||||
# External dependencies
|
||||
clap = { version = "4.5.3", features = [ "derive" ] }
|
||||
clap = { version = "4.5.4", features = [ "derive" ] }
|
||||
serde = { version = "1.0.197", features = [ "derive" ] }
|
||||
|
||||
[build-dependencies]
|
||||
clap = { version = "4.5.3", features = [ "derive" ] }
|
||||
clap = { version = "4.5.4", features = [ "derive" ] }
|
||||
clap_complete = "4.5.1"
|
||||
clap_complete_nushell = "4.5.1"
|
||||
clap_complete_fig = "4.5.0"
|
||||
|
@ -13,14 +13,14 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = "1.0.81"
|
||||
arc-swap = "1.7.0"
|
||||
arc-swap = "1.7.1"
|
||||
crossterm = "0.27.0"
|
||||
futures = "0.3.30"
|
||||
glob = "0.3.1"
|
||||
indexmap = "2.2.5"
|
||||
indexmap = "2.2.6"
|
||||
md-5 = "0.10.6"
|
||||
ratatui = "0.26.1"
|
||||
serde = { version = "1.0.197", features = [ "derive" ] }
|
||||
shell-words = "1.1.0"
|
||||
toml = { version = "0.8.11", features = [ "preserve_order" ] }
|
||||
toml = { version = "0.8.12", features = [ "preserve_order" ] }
|
||||
validator = { version = "0.17.0", features = [ "derive" ] }
|
||||
|
@ -21,16 +21,16 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.4" }
|
||||
# External dependencies
|
||||
anyhow = "1.0.81"
|
||||
base64 = "0.22.0"
|
||||
bitflags = "2.4.2"
|
||||
bitflags = "2.5.0"
|
||||
crossterm = "0.27.0"
|
||||
futures = "0.3.30"
|
||||
indexmap = "2.2.5"
|
||||
indexmap = "2.2.6"
|
||||
notify = { version = "6.1.1", default-features = false, features = [ "macos_fsevent" ] }
|
||||
parking_lot = "0.12.1"
|
||||
ratatui = "0.26.1"
|
||||
regex = "1.10.3"
|
||||
regex = "1.10.4"
|
||||
serde = "1.0.197"
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
tokio-stream = "0.1.15"
|
||||
tokio-util = "0.7.10"
|
||||
unicode-width = "0.1.11"
|
||||
|
@ -17,8 +17,8 @@ anyhow = "1.0.81"
|
||||
mlua = { version = "0.9.6", features = [ "lua54", "vendored" ] }
|
||||
parking_lot = "0.12.1"
|
||||
serde = { version = "1.0.197", features = [ "derive" ] }
|
||||
serde_json = "1.0.114"
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
serde_json = "1.0.115"
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
|
||||
# Logging
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
|
@ -28,7 +28,7 @@ futures = "0.3.30"
|
||||
mlua = { version = "0.9.6", features = [ "lua54", "vendored" ] }
|
||||
ratatui = "0.26.1"
|
||||
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
tokio-util = "0.7.10"
|
||||
unicode-width = "0.1.11"
|
||||
|
||||
|
@ -19,7 +19,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.4" }
|
||||
# External dependencies
|
||||
ansi-to-tui = "3.1.0"
|
||||
anyhow = "1.0.81"
|
||||
arc-swap = "1.7.0"
|
||||
arc-swap = "1.7.1"
|
||||
crossterm = "0.27.0"
|
||||
futures = "0.3.30"
|
||||
md-5 = "0.10.6"
|
||||
@ -27,15 +27,17 @@ mlua = { version = "0.9.6", features = [ "lua54", "vendored", "serializ
|
||||
parking_lot = "0.12.1"
|
||||
ratatui = "0.26.1"
|
||||
serde = "1.0.197"
|
||||
serde_json = "1.0.114"
|
||||
serde_json = "1.0.115"
|
||||
shell-escape = "0.1.5"
|
||||
shell-words = "1.1.0"
|
||||
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
tokio-util = "0.7.10"
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
unicode-width = "0.1.11"
|
||||
yazi-prebuild = "0.1.2"
|
||||
|
||||
# Logging
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
uzers = "0.11.3"
|
||||
|
@ -15,4 +15,4 @@ yazi-shared = { path = "../yazi-shared", version = "0.2.4" }
|
||||
# External dependencies
|
||||
anyhow = "1.0.81"
|
||||
mlua = { version = "0.9.6", features = [ "lua54", "vendored" ] }
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
|
@ -23,8 +23,8 @@ base64 = "0.22.0"
|
||||
crossterm = "0.27.0"
|
||||
futures = "0.3.30"
|
||||
parking_lot = "0.12.1"
|
||||
regex = "1.10.3"
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
regex = "1.10.4"
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
tokio-stream = "0.1.15"
|
||||
|
||||
# Logging
|
||||
@ -34,4 +34,4 @@ tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_lev
|
||||
libc = "0.2.153"
|
||||
|
||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||
trash = "4.0.0"
|
||||
trash = "4.1.0"
|
||||
|
@ -10,16 +10,19 @@ repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.81"
|
||||
bitflags = "2.4.2"
|
||||
bitflags = "2.5.0"
|
||||
crossterm = "0.27.0"
|
||||
dirs = "5.0.1"
|
||||
futures = "0.3.30"
|
||||
parking_lot = "0.12.1"
|
||||
percent-encoding = "2.3.1"
|
||||
ratatui = "0.26.1"
|
||||
regex = "1.10.3"
|
||||
regex = "1.10.4"
|
||||
serde = "1.0.197"
|
||||
tokio = { version = "1.36.0", features = [ "full" ] }
|
||||
tokio = { version = "1.37.0", features = [ "full" ] }
|
||||
|
||||
# Logging
|
||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = "0.2.153"
|
||||
|
34
yazi-shared/src/term/csi_u.rs
Normal file
34
yazi-shared/src/term/csi_u.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use tokio::{io::{stdin, AsyncReadExt, BufReader}, time::timeout};
|
||||
use tracing::error;
|
||||
|
||||
use super::Term;
|
||||
|
||||
impl Term {
|
||||
pub async fn read_until_da1() -> Result<String> {
|
||||
let read = async {
|
||||
let mut stdin = BufReader::new(stdin());
|
||||
let mut buf = String::with_capacity(200);
|
||||
loop {
|
||||
let mut c = [0; 1];
|
||||
if stdin.read(&mut c).await? == 0 {
|
||||
bail!("unexpected EOF");
|
||||
}
|
||||
if c[0] == b'c' && buf.contains("\x1b[?") {
|
||||
break;
|
||||
}
|
||||
buf.push(c[0] as char);
|
||||
}
|
||||
Ok(buf)
|
||||
};
|
||||
|
||||
let timeout = timeout(Duration::from_secs(10), read).await;
|
||||
if let Err(ref e) = timeout {
|
||||
error!("read_until_da1: {e:?}");
|
||||
}
|
||||
|
||||
timeout?
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
mod csi_u;
|
||||
mod cursor;
|
||||
mod term;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::{io::{self, stderr, BufWriter, Stderr, Write}, mem, ops::{Deref, DerefMut}, sync::atomic::{AtomicBool, Ordering}};
|
||||
|
||||
use anyhow::Result;
|
||||
use crossterm::{event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen, WindowSize}};
|
||||
use crossterm::{cursor::{RestorePosition, SavePosition}, event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, style::Print, terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen, WindowSize}};
|
||||
use ratatui::{backend::CrosstermBackend, buffer::Buffer, layout::Rect, CompletedFrame, Frame, Terminal};
|
||||
|
||||
static CSI_U: AtomicBool = AtomicBool::new(false);
|
||||
@ -21,9 +21,18 @@ impl Term {
|
||||
};
|
||||
|
||||
enable_raw_mode()?;
|
||||
queue!(stderr(), EnterAlternateScreen, EnableBracketedPaste, EnableFocusChange)?;
|
||||
execute!(
|
||||
BufWriter::new(stderr()),
|
||||
EnterAlternateScreen,
|
||||
EnableBracketedPaste,
|
||||
EnableFocusChange,
|
||||
SavePosition,
|
||||
Print("\x1b[?u\x1b[c"),
|
||||
RestorePosition
|
||||
)?;
|
||||
|
||||
if let Ok(true) = supports_keyboard_enhancement() {
|
||||
let resp = futures::executor::block_on(Self::read_until_da1());
|
||||
if resp.is_ok_and(|s| s.contains("\x1b[?0u")) {
|
||||
queue!(
|
||||
stderr(),
|
||||
PushKeyboardEnhancementFlags(
|
||||
|
Loading…
Reference in New Issue
Block a user