mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: terminal response detection under async stdin
This commit is contained in:
parent
22c8f370dc
commit
8655cf0193
4 changed files with 90 additions and 5 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -726,9 +726,9 @@ checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
|
|||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
|
|
@ -2390,9 +2390,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||
|
||||
[[package]]
|
||||
name = "smawk"
|
||||
|
|
@ -3324,10 +3324,12 @@ dependencies = [
|
|||
"crossterm",
|
||||
"futures",
|
||||
"image",
|
||||
"libc",
|
||||
"ratatui",
|
||||
"scopeguard",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
"yazi-config",
|
||||
"yazi-macro",
|
||||
"yazi-shared",
|
||||
|
|
|
|||
|
|
@ -26,5 +26,11 @@ scopeguard = { workspace = true }
|
|||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = { workspace = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows-sys = { version = "0.59.0", features = [ "Win32_UI_Shell" ] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
yazi_macro::mod_pub!(drivers);
|
||||
|
||||
yazi_macro::mod_flat!(adapter brand dimension emulator image info mux unknown);
|
||||
yazi_macro::mod_flat!(adapter brand dimension emulator image info mux stdin unknown);
|
||||
|
||||
use yazi_shared::{SyncCell, in_wsl};
|
||||
|
||||
|
|
|
|||
77
yazi-adapter/src/stdin.rs
Normal file
77
yazi-adapter/src/stdin.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
use std::{io, ops::{Deref, DerefMut}};
|
||||
|
||||
pub struct AsyncStdin {
|
||||
inner: std::io::StdinLock<'static>,
|
||||
#[cfg(unix)]
|
||||
fds: libc::fd_set,
|
||||
}
|
||||
|
||||
impl Deref for AsyncStdin {
|
||||
type Target = std::io::StdinLock<'static>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl DerefMut for AsyncStdin {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl AsyncStdin {
|
||||
pub fn new(inner: std::io::StdinLock<'static>) -> Self {
|
||||
let mut me = Self { inner, fds: unsafe { std::mem::MaybeUninit::zeroed().assume_init() } };
|
||||
me.reset();
|
||||
me
|
||||
}
|
||||
|
||||
pub fn poll(&mut self, timeout: std::time::Duration) -> std::io::Result<bool> {
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
let mut tv = libc::timeval {
|
||||
tv_sec: timeout.as_secs() as libc::time_t,
|
||||
tv_usec: timeout.subsec_micros() as libc::suseconds_t,
|
||||
};
|
||||
|
||||
let result = unsafe {
|
||||
libc::select(
|
||||
self.inner.as_raw_fd() + 1,
|
||||
&mut self.fds,
|
||||
std::ptr::null_mut(),
|
||||
std::ptr::null_mut(),
|
||||
&mut tv,
|
||||
)
|
||||
};
|
||||
|
||||
match result {
|
||||
-1 => Err(io::Error::last_os_error()),
|
||||
0 => Ok(false),
|
||||
_ => {
|
||||
self.reset();
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
unsafe {
|
||||
libc::FD_ZERO(&mut self.fds);
|
||||
libc::FD_SET(self.inner.as_raw_fd(), &mut self.fds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl AsyncStdin {
|
||||
pub fn new(inner: std::io::StdinLock<'static>) -> Self { Self { inner } }
|
||||
|
||||
pub fn poll(&mut self) -> std::io::Result<bool> {
|
||||
let handle = HANDLE(self.inner.as_raw_handle() as isize);
|
||||
|
||||
match unsafe { WaitForSingleObject(handle, 5000) } {
|
||||
WAIT_TIMEOUT => Ok(false),
|
||||
_ => Ok(true),
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue