diff --git a/Cargo.lock b/Cargo.lock index edc3ca34..5e7d3cc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.7" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -199,9 +199,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "block-buffer" @@ -281,9 +281,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.17" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80932e03c33999b9235edb8655bc9df3204adc9887c2f95b50cb1deb9fd54253" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -291,9 +291,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.17" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c0db58c659eef1c73e444d298c27322a1b52f6927d2ad470c0c0f96fa7b8fa" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -303,9 +303,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.7" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb0d4825b75ff281318c393e8e1b80c4da9fb75a6b1d98547d389d6fe1f48d2" +checksum = "eaf7dcb7c21d8ca1a2482ee0f1d341f437c9a7af6ca6da359dc5e1b164e98215" dependencies = [ "clap", ] @@ -447,7 +447,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "crossterm_winapi", "futures-core", "libc", @@ -599,9 +599,9 @@ dependencies = [ [[package]] name = "fdeflate" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] @@ -830,9 +830,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "home" @@ -1047,7 +1047,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall", ] @@ -1063,9 +1063,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -1232,7 +1232,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "filetime", "fsevent-sys", "inotify", @@ -1404,9 +1404,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "plist" @@ -1467,9 +1467,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1507,7 +1507,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5659e52e4ba6e07b2dad9f1158f578ef84a73762625ddb51536019f34d180eb" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cassowary", "crossterm", "indoc", @@ -1522,9 +1522,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -1532,9 +1532,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -1562,9 +1562,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -1574,9 +1574,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" dependencies = [ "aho-corasick", "memchr", @@ -1613,7 +1613,7 @@ version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", @@ -1777,9 +1777,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" @@ -2155,9 +2155,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -2263,11 +2263,12 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "vergen" -version = "8.2.10" +version = "8.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a78365c3f8ca9dc5428a9f5c6349558c3f9f3eeb65e3fc00b6a981379462947" +checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525" dependencies = [ "anyhow", + "cfg-if", "rustversion", "time", ] @@ -2663,7 +2664,7 @@ version = "0.2.2" dependencies = [ "anyhow", "base64", - "bitflags 2.4.1", + "bitflags 2.4.2", "clipboard-win", "crossterm", "futures", @@ -2701,6 +2702,7 @@ dependencies = [ "signal-hook-tokio", "syntect", "tokio", + "tokio-util", "tracing", "tracing-appender", "tracing-subscriber", @@ -2772,7 +2774,7 @@ name = "yazi-shared" version = "0.2.2" dependencies = [ "anyhow", - "bitflags 2.4.1", + "bitflags 2.4.2", "crossterm", "futures", "libc", diff --git a/yazi-config/src/keymap/mod.rs b/yazi-config/src/keymap/mod.rs index 76a1c2c4..c531882a 100644 --- a/yazi-config/src/keymap/mod.rs +++ b/yazi-config/src/keymap/mod.rs @@ -4,7 +4,7 @@ mod key; mod keymap; pub use control::*; -pub use exec::*; #[allow(unused_imports)] +pub use exec::*; pub use key::*; pub use keymap::*; diff --git a/yazi-config/src/plugin/mod.rs b/yazi-config/src/plugin/mod.rs index ec375606..6bd03a96 100644 --- a/yazi-config/src/plugin/mod.rs +++ b/yazi-config/src/plugin/mod.rs @@ -2,6 +2,7 @@ mod exec; mod plugin; mod props; +#[allow(unused_imports)] pub use exec::*; pub use plugin::*; pub use props::*; diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index adca7683..97c4b3a1 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -24,9 +24,10 @@ fdlimit = "^0" futures = "^0" mlua = { version = "^0", features = [ "lua54", "vendored" ] } ratatui = "^0" -tokio = { version = "^1", features = [ "parking_lot" ] } -unicode-width = "^0" syntect = { version = "^5", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } +tokio = { version = "^1", features = [ "parking_lot" ] } +tokio-util = "^0" +unicode-width = "^0" # Logging tracing = { version = "^0", features = [ "max_level_debug", "release_max_level_warn" ] } diff --git a/yazi-fm/src/app/commands/mod.rs b/yazi-fm/src/app/commands/mod.rs index 556cb9a5..d40453a6 100644 --- a/yazi-fm/src/app/commands/mod.rs +++ b/yazi-fm/src/app/commands/mod.rs @@ -2,5 +2,6 @@ mod plugin; mod quit; mod render; mod resize; +mod resume; mod stop; mod update_progress; diff --git a/yazi-fm/src/app/commands/resume.rs b/yazi-fm/src/app/commands/resume.rs new file mode 100644 index 00000000..ecdf925c --- /dev/null +++ b/yazi-fm/src/app/commands/resume.rs @@ -0,0 +1,16 @@ +use yazi_shared::{event::Exec, term::Term}; + +use crate::app::App; + +impl App { + pub(crate) fn resume(&mut self, _: &Exec) { + self.cx.manager.active_mut().preview.reset_image(); + self.term = Some(Term::start().unwrap()); + + // While the app resumes, it's possible that the terminal size has changed. + // We need to trigger a resize, and render the UI based on the resized area. + self.resize().unwrap(); + + self.signals.resume(); + } +} diff --git a/yazi-fm/src/app/commands/stop.rs b/yazi-fm/src/app/commands/stop.rs index 4bb93d8d..64529e0d 100644 --- a/yazi-fm/src/app/commands/stop.rs +++ b/yazi-fm/src/app/commands/stop.rs @@ -1,38 +1,24 @@ use tokio::sync::oneshot; -use yazi_shared::{event::Exec, term::Term}; +use yazi_shared::event::Exec; use crate::app::App; pub struct Opt { - state: bool, - tx: Option>, + tx: Option>, } impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { state: e.args.first().map_or(false, |s| s == "true"), tx: e.take_data() } - } + fn from(e: &Exec) -> Self { Self { tx: e.take_data() } } } impl App { - pub(crate) fn stop(&mut self, opt: impl TryInto) { - let Ok(opt) = opt.try_into() else { - return; - }; - + pub(crate) fn stop(&mut self, opt: impl Into) { self.cx.manager.active_mut().preview.reset_image(); - if opt.state { - self.signals.stop_term(true); - self.term = None; - } else { - self.term = Some(Term::start().unwrap()); - self.signals.stop_term(false); - // While the app resumes, it's possible that the terminal size has changed. - // We need to trigger a resize, and render the UI based on the resized area. - self.resize().unwrap(); - } - if let Some(tx) = opt.tx { + self.signals.stop(); + self.term = None; + + if let Some(tx) = opt.into().tx { tx.send(()).ok(); } } diff --git a/yazi-fm/src/executor.rs b/yazi-fm/src/executor.rs index 2309e50e..010eb57e 100644 --- a/yazi-fm/src/executor.rs +++ b/yazi-fm/src/executor.rs @@ -86,6 +86,7 @@ impl<'a> Executor<'a> { on!(plugin_do); on!(update_progress); on!(stop); + on!(resume); } fn manager(&mut self, exec: &Exec) { diff --git a/yazi-fm/src/signals.rs b/yazi-fm/src/signals.rs index f3e4eaa7..d7f93891 100644 --- a/yazi-fm/src/signals.rs +++ b/yazi-fm/src/signals.rs @@ -1,42 +1,38 @@ use anyhow::Result; use crossterm::event::{Event as CrosstermEvent, EventStream, KeyEvent, KeyEventKind}; use futures::StreamExt; -use tokio::{select, sync::{mpsc::{self, UnboundedReceiver, UnboundedSender}, oneshot}, task::JoinHandle}; +use tokio::{select, sync::mpsc, task::JoinHandle}; +use tokio_util::sync::CancellationToken; use yazi_shared::event::Event; pub(super) struct Signals { - tx: UnboundedSender, - pub(super) rx: UnboundedReceiver, - - term_stop_tx: Option>, - term_stop_rx: Option>, + tx: mpsc::UnboundedSender, + pub rx: mpsc::UnboundedReceiver, + ct: CancellationToken, } impl Signals { pub(super) fn start() -> Result { let (tx, rx) = mpsc::unbounded_channel(); - let (term_tx, term_rx) = oneshot::channel(); - - let mut signals = - Self { tx: tx.clone(), rx, term_stop_tx: Some(term_tx), term_stop_rx: Some(term_rx) }; + let ct = CancellationToken::new(); + let mut signals = Self { tx: tx.clone(), rx, ct }; + Event::init(tx); signals.spawn_system_task()?; signals.spawn_crossterm_task(); - Event::init(tx); Ok(signals) } - pub(super) fn stop_term(&mut self, state: bool) { - if state == self.term_stop_tx.is_none() { - return; + pub(super) fn stop(&mut self) { + if !self.ct.is_cancelled() { + self.ct.cancel(); } + } - if let Some(tx) = self.term_stop_tx.take() { - tx.send(()).ok(); - } else { - let (tx, rx) = oneshot::channel(); - (self.term_stop_tx, self.term_stop_rx) = (Some(tx), Some(rx)); + pub(super) fn resume(&mut self) { + if self.ct.is_cancelled() { + self.ct = CancellationToken::new(); self.spawn_crossterm_task(); } } @@ -47,9 +43,8 @@ impl Signals { #[cfg(unix)] fn spawn_system_task(&self) -> Result> { use libc::{SIGCONT, SIGHUP, SIGINT, SIGQUIT, SIGTERM}; - use yazi_scheduler::Scheduler; + use yazi_scheduler::{Scheduler, BLOCKER}; - let tx = self.tx.clone(); let mut signals = signal_hook_tokio::Signals::new([ // Terminating signals SIGHUP, SIGTERM, SIGQUIT, SIGINT, // @@ -57,8 +52,13 @@ impl Signals { SIGCONT, ])?; + let tx = self.tx.clone(); Ok(tokio::spawn(async move { while let Some(signal) = signals.next().await { + if BLOCKER.try_acquire().is_err() { + continue; + } + match signal { SIGHUP | SIGTERM | SIGQUIT | SIGINT => { if tx.send(Event::Quit(Default::default())).is_err() { @@ -73,15 +73,13 @@ impl Signals { } fn spawn_crossterm_task(&mut self) -> JoinHandle<()> { - let tx = self.tx.clone(); - let mut stop_rx = self.term_stop_rx.take().unwrap(); + let mut reader = EventStream::new(); + let (tx, ct) = (self.tx.clone(), self.ct.clone()); tokio::spawn(async move { - let mut reader = EventStream::new(); - loop { select! { - _ = &mut stop_rx => break, + _ = ct.cancelled() => break, Some(Ok(event)) = reader.next() => { let event = match event { // We need to check key event kind; diff --git a/yazi-plugin/src/process/child.rs b/yazi-plugin/src/process/child.rs index f08f105b..8a1668c1 100644 --- a/yazi-plugin/src/process/child.rs +++ b/yazi-plugin/src/process/child.rs @@ -7,7 +7,7 @@ use super::Status; pub struct Child { inner: tokio::process::Child, - stdin: Option, + _stdin: Option, stdout: Option>, stderr: Option>, } @@ -17,7 +17,7 @@ impl Child { let stdin = inner.stdin.take(); let stdout = inner.stdout.take().map(BufReader::new); let stderr = inner.stderr.take().map(BufReader::new); - Self { inner, stdin, stdout, stderr } + Self { inner, _stdin: stdin, stdout, stderr } } } diff --git a/yazi-plugin/src/utils/plugin.rs b/yazi-plugin/src/utils/plugin.rs index 827d8976..88bf844d 100644 --- a/yazi-plugin/src/utils/plugin.rs +++ b/yazi-plugin/src/utils/plugin.rs @@ -7,7 +7,7 @@ impl Utils { ya.set( "plugin_retrieve", lua.create_async_function( - |_, (name, calls, args): (String, usize, Variadic)| async move { Ok(()) }, + |_, (_name, _calls, _args): (String, usize, Variadic)| async move { Ok(()) }, )?, )?; diff --git a/yazi-scheduler/src/scheduler.rs b/yazi-scheduler/src/scheduler.rs index c1a910f3..7270cc11 100644 --- a/yazi-scheduler/src/scheduler.rs +++ b/yazi-scheduler/src/scheduler.rs @@ -164,15 +164,12 @@ impl Scheduler { pub async fn app_stop() { let (tx, rx) = oneshot::channel::<()>(); - emit!(Call(Exec::call("stop", vec!["true".to_string()]).with_data(Some(tx)).vec(), Layer::App)); + emit!(Call(Exec::call("stop", vec![]).with_data(tx).vec(), Layer::App)); rx.await.ok(); } pub fn app_resume() { - emit!(Call( - Exec::call("stop", vec!["false".to_string()]).with_data(None::>).vec(), - Layer::App - )); + emit!(Call(Exec::call("resume", vec![]).vec(), Layer::App)); } pub fn file_cut(&self, from: Url, mut to: Url, force: bool) { diff --git a/yazi-shared/src/event/event.rs b/yazi-shared/src/event/event.rs index 756c9d66..256cabb5 100644 --- a/yazi-shared/src/event/event.rs +++ b/yazi-shared/src/event/event.rs @@ -1,12 +1,12 @@ use std::ffi::OsString; use crossterm::event::KeyEvent; -use tokio::sync::{mpsc::UnboundedSender, oneshot}; +use tokio::sync::{mpsc, oneshot}; use super::Exec; use crate::{term::Term, Layer, RoCell}; -static TX: RoCell> = RoCell::new(); +static TX: RoCell> = RoCell::new(); #[derive(Debug)] pub enum Event { @@ -26,11 +26,12 @@ pub struct EventQuit { impl Event { #[inline] - pub fn init(tx: UnboundedSender) { TX.init(tx); } + pub fn init(tx: mpsc::UnboundedSender) { TX.init(tx); } #[inline] pub fn emit(self) { TX.send(self).ok(); } + #[inline] pub async fn wait(self, rx: oneshot::Receiver) -> T { TX.send(self).ok(); rx.await.unwrap_or_else(|_| Term::goodbye(|| false))