diff --git a/Cargo.lock b/Cargo.lock index 6e341b84..f1ef14a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,9 +585,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.61" +version = "4.5.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39615915e2ece2550c0149addac32fb5bd312c657f43845bb9088cb9c8a7c992" +checksum = "004eef6b14ce34759aa7de4aea3217e368f463f46a3ed3764ca4b5a4404003b4" dependencies = [ "clap", ] @@ -3430,9 +3430,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ "serde_core", ] @@ -3874,9 +3874,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.8" +version = "0.9.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" dependencies = [ "indexmap", "serde_core", @@ -3889,33 +3889,33 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3947,9 +3947,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -4747,6 +4747,7 @@ name = "yazi-binding" version = "25.9.15" dependencies = [ "ansi-to-tui", + "futures", "hashbrown 0.16.1", "mlua", "paste", @@ -5075,18 +5076,17 @@ dependencies = [ "anyhow", "async-priority-channel", "foldhash 0.2.0", - "futures", "hashbrown 0.16.1", "libc", "lru 0.16.2", "mlua", "ordered-float 5.1.0", "parking_lot", - "scopeguard", "serde", "tokio", "tokio-util", "tracing", + "yazi-binding", "yazi-config", "yazi-dds", "yazi-fs", diff --git a/Cargo.toml b/Cargo.toml index 7b9f7f0a..fa76c8db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,8 +59,8 @@ thiserror = "2.0.17" tokio = { version = "1.48.0", features = [ "full" ] } tokio-stream = "0.1.17" tokio-util = "0.7.17" -toml = { version = "0.9.8" } -tracing = { version = "0.1.43", features = [ "max_level_debug", "release_max_level_debug" ] } +toml = { version = "0.9.10" } +tracing = { version = "0.1.44", features = [ "max_level_debug", "release_max_level_debug" ] } twox-hash = { version = "2.1.2", default-features = false, features = [ "std", "random", "xxhash3_128" ] } typed-path = "0.12.0" unicode-width = { version = "0.2.0", default-features = false } diff --git a/yazi-actor/src/mgr/bulk_rename.rs b/yazi-actor/src/mgr/bulk_rename.rs index c8308417..9c853bd9 100644 --- a/yazi-actor/src/mgr/bulk_rename.rs +++ b/yazi-actor/src/mgr/bulk_rename.rs @@ -5,6 +5,7 @@ use crossterm::{execute, style::Print}; use hashbrown::HashMap; use scopeguard::defer; use tokio::io::AsyncWriteExt; +use yazi_binding::Permit; use yazi_config::{YAZI, opener::OpenerRule}; use yazi_dds::Pubsub; use yazi_fs::{File, FilesOp, Splatter, max_common_root, path::skip_url, provider::{FileBuilder, Provider, local::{Gate, Local}}}; @@ -65,8 +66,7 @@ impl Actor for BulkRename { ) .await; - let _permit = HIDER.acquire().await.unwrap(); - defer!(AppProxy::resume()); + let _permit = Permit::new(HIDER.acquire().await.unwrap(), AppProxy::resume()); AppProxy::stop().await; let new: Vec<_> = Local::regular(&tmp) diff --git a/yazi-actor/src/tasks/inspect.rs b/yazi-actor/src/tasks/inspect.rs index f3bd889d..dc78acd5 100644 --- a/yazi-actor/src/tasks/inspect.rs +++ b/yazi-actor/src/tasks/inspect.rs @@ -4,6 +4,7 @@ use anyhow::Result; use crossterm::{execute, terminal::{disable_raw_mode, enable_raw_mode}}; use scopeguard::defer; use tokio::{io::{AsyncReadExt, stdin}, select, sync::mpsc, time}; +use yazi_binding::Permit; use yazi_macro::succ; use yazi_parser::VoidOpt; use yazi_proxy::{AppProxy, HIDER}; @@ -26,7 +27,7 @@ impl Actor for Inspect { }; tokio::spawn(async move { - let _permit = HIDER.acquire().await.unwrap(); + let _permit = Permit::new(HIDER.acquire().await.unwrap(), AppProxy::resume()); let (tx, mut rx) = mpsc::unbounded_channel(); let buffered = { @@ -37,9 +38,7 @@ impl Actor for Inspect { task.logs.clone() }; - defer!(AppProxy::resume()); AppProxy::stop().await; - terminal_clear(TTY.writer()).ok(); TTY.writer().write_all(buffered.as_bytes()).ok(); TTY.writer().flush().ok(); diff --git a/yazi-binding/Cargo.toml b/yazi-binding/Cargo.toml index cd8077cd..622720c2 100644 --- a/yazi-binding/Cargo.toml +++ b/yazi-binding/Cargo.toml @@ -24,6 +24,7 @@ yazi-shared = { path = "../yazi-shared", version = "25.9.15" } # External dependencies ansi-to-tui = { workspace = true } +futures = { workspace = true } hashbrown = { workspace = true } mlua = { workspace = true } paste = { workspace = true } diff --git a/yazi-binding/src/permit.rs b/yazi-binding/src/permit.rs index 2d16037f..19acf379 100644 --- a/yazi-binding/src/permit.rs +++ b/yazi-binding/src/permit.rs @@ -1,42 +1,51 @@ use std::{mem, ops::Deref}; +use futures::{FutureExt, future::BoxFuture}; use mlua::{UserData, prelude::LuaUserDataMethods}; use tokio::sync::SemaphorePermit; -pub type PermitRef = mlua::UserDataRef>; +pub type PermitRef = mlua::UserDataRef; -pub struct Permit { +pub struct Permit { inner: Option>, - destruct: Option, + destruct: Option>, } -impl Deref for Permit { +impl Deref for Permit { type Target = Option>; fn deref(&self) -> &Self::Target { &self.inner } } -impl Permit { - pub fn new(inner: SemaphorePermit<'static>, f: F) -> Self { - Self { inner: Some(inner), destruct: Some(f) } +impl Permit { + pub fn new(inner: SemaphorePermit<'static>, f: F) -> Self + where + F: Future + 'static + Send, + { + Self { inner: Some(inner), destruct: Some(f.boxed()) } } - fn dropping(&mut self) { - if let Some(f) = self.destruct.take() { - f(); - } - if let Some(p) = self.inner.take() { - mem::drop(p); + fn dropping(&mut self) -> impl Future + 'static { + let inner = self.inner.take(); + let destruct = self.destruct.take(); + + async move { + if let Some(f) = destruct { + f.await; + } + if let Some(p) = inner { + mem::drop(p); + } } } } -impl Drop for Permit { - fn drop(&mut self) { self.dropping(); } +impl Drop for Permit { + fn drop(&mut self) { tokio::spawn(self.dropping()); } } -impl UserData for Permit { +impl UserData for Permit { fn add_methods>(methods: &mut M) { - methods.add_method_mut("drop", |_, me, ()| Ok(me.dropping())); + methods.add_async_method_mut("drop", |_, mut me, ()| async move { Ok(me.dropping().await) }); } } diff --git a/yazi-boot/Cargo.toml b/yazi-boot/Cargo.toml index a7aa5449..96cd9b92 100644 --- a/yazi-boot/Cargo.toml +++ b/yazi-boot/Cargo.toml @@ -30,7 +30,7 @@ yazi-shared = { path = "../yazi-shared", version = "25.9.15" } # External dependencies clap = { workspace = true } -clap_complete = "4.5.61" +clap_complete = "4.5.62" clap_complete_fig = "4.5.2" clap_complete_nushell = "4.5.10" vergen-gitcl = { version = "1.0.8", features = [ "build", "rustc" ] } diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index 8be1fcd0..b62fa549 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -44,7 +44,7 @@ yazi-shared = { path = "../yazi-shared", version = "25.9.15" } # External build dependencies anyhow = { workspace = true } clap = { workspace = true } -clap_complete = "4.5.61" +clap_complete = "4.5.62" clap_complete_fig = "4.5.2" clap_complete_nushell = "4.5.10" serde_json = { workspace = true } diff --git a/yazi-fm/src/signals.rs b/yazi-fm/src/signals.rs index 350a0c66..78a0f505 100644 --- a/yazi-fm/src/signals.rs +++ b/yazi-fm/src/signals.rs @@ -44,7 +44,7 @@ impl Signals { } }); } - SIGCONT if HIDER.try_acquire().is_ok() => AppProxy::resume(), + SIGCONT if HIDER.try_acquire().is_ok() => _ = tokio::spawn(AppProxy::resume()), _ => {} } true diff --git a/yazi-plugin/src/elements/elements.rs b/yazi-plugin/src/elements/elements.rs index 4fd14a1e..08466c5a 100644 --- a/yazi-plugin/src/elements/elements.rs +++ b/yazi-plugin/src/elements/elements.rs @@ -48,14 +48,14 @@ pub(super) fn hide(lua: &Lua) -> mlua::Result { return Err("Cannot call `ui.hide()` during app initialization".into_lua_err()); } - if lua.named_registry_value::>("HIDE_PERMIT").is_ok_and(|h| h.is_some()) { + if lua.named_registry_value::("HIDE_PERMIT").is_ok_and(|h| h.is_some()) { return Err("Cannot hide while already hidden".into_lua_err()); } let permit = HIDER.acquire().await.unwrap(); AppProxy::stop().await; - lua.set_named_registry_value("HIDE_PERMIT", Permit::new(permit, AppProxy::resume as fn()))?; + lua.set_named_registry_value("HIDE_PERMIT", Permit::new(permit, AppProxy::resume()))?; lua.named_registry_value::("HIDE_PERMIT") })?; diff --git a/yazi-plugin/src/utils/app.rs b/yazi-plugin/src/utils/app.rs index 3e5acc77..ec48ebbd 100644 --- a/yazi-plugin/src/utils/app.rs +++ b/yazi-plugin/src/utils/app.rs @@ -35,14 +35,14 @@ impl Utils { lua.create_async_function(|lua, ()| async move { deprecate!(lua, "`ya.hide()` is deprecated, use `ui.hide()` instead, in your {}\nSee #2939 for more details: https://github.com/sxyazi/yazi/pull/2939"); - if lua.named_registry_value::>("HIDE_PERMIT").is_ok_and(|h| h.is_some()) { + if lua.named_registry_value::("HIDE_PERMIT").is_ok_and(|h| h.is_some()) { return Err("Cannot hide while already hidden".into_lua_err()); } let permit = HIDER.acquire().await.unwrap(); AppProxy::stop().await; - lua.set_named_registry_value("HIDE_PERMIT", Permit::new(permit, AppProxy::resume as fn()))?; + lua.set_named_registry_value("HIDE_PERMIT", Permit::new(permit, AppProxy::resume()))?; lua.named_registry_value::("HIDE_PERMIT") }) } diff --git a/yazi-proxy/src/app.rs b/yazi-proxy/src/app.rs index de62de15..7a15807a 100644 --- a/yazi-proxy/src/app.rs +++ b/yazi-proxy/src/app.rs @@ -13,8 +13,10 @@ impl AppProxy { rx.await.ok(); } - pub fn resume() { - emit!(Call(relay!(app:resume))); + pub async fn resume() { + let (tx, rx) = oneshot::channel::<()>(); + emit!(Call(relay!(app:resume).with_any("tx", tx))); + rx.await.ok(); } pub fn notify(opt: NotifyOpt) { diff --git a/yazi-scheduler/Cargo.toml b/yazi-scheduler/Cargo.toml index fda89e5e..01ae27d0 100644 --- a/yazi-scheduler/Cargo.toml +++ b/yazi-scheduler/Cargo.toml @@ -12,27 +12,26 @@ repository = "https://github.com/sxyazi/yazi" workspace = true [dependencies] -yazi-config = { path = "../yazi-config", version = "25.9.15" } -yazi-dds = { path = "../yazi-dds", version = "25.9.15" } -yazi-fs = { path = "../yazi-fs", version = "25.9.15" } -yazi-macro = { path = "../yazi-macro", version = "25.9.15" } -yazi-parser = { path = "../yazi-parser", version = "25.9.15" } -yazi-plugin = { path = "../yazi-plugin", version = "25.9.15" } -yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" } -yazi-shared = { path = "../yazi-shared", version = "25.9.15" } -yazi-vfs = { path = "../yazi-vfs", version = "25.9.15" } +yazi-binding = { path = "../yazi-binding", version = "25.9.15" } +yazi-config = { path = "../yazi-config", version = "25.9.15" } +yazi-dds = { path = "../yazi-dds", version = "25.9.15" } +yazi-fs = { path = "../yazi-fs", version = "25.9.15" } +yazi-macro = { path = "../yazi-macro", version = "25.9.15" } +yazi-parser = { path = "../yazi-parser", version = "25.9.15" } +yazi-plugin = { path = "../yazi-plugin", version = "25.9.15" } +yazi-proxy = { path = "../yazi-proxy", version = "25.9.15" } +yazi-shared = { path = "../yazi-shared", version = "25.9.15" } +yazi-vfs = { path = "../yazi-vfs", version = "25.9.15" } # External dependencies anyhow = { workspace = true } async-priority-channel = "0.2.0" foldhash = { workspace = true } -futures = { workspace = true } hashbrown = { workspace = true } lru = { workspace = true } mlua = { workspace = true } ordered-float = { workspace = true } parking_lot = { workspace = true } -scopeguard = { workspace = true } serde = { workspace = true } tokio = { workspace = true } tokio-util = { workspace = true } diff --git a/yazi-scheduler/src/process/process.rs b/yazi-scheduler/src/process/process.rs index a9fd59d3..2262bf7b 100644 --- a/yazi-scheduler/src/process/process.rs +++ b/yazi-scheduler/src/process/process.rs @@ -1,6 +1,6 @@ use anyhow::{Result, anyhow}; -use scopeguard::defer; use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::mpsc}; +use yazi_binding::Permit; use yazi_proxy::{AppProxy, HIDER}; use super::{ProcessInBg, ProcessInBlock, ProcessInOrphan, ShellOpt}; @@ -14,8 +14,7 @@ impl Process { pub(crate) fn new(ops: &mpsc::UnboundedSender) -> Self { Self { ops: ops.into() } } pub(crate) async fn block(&self, task: ProcessInBlock) -> Result<(), ProcessOutBlock> { - let _permit = HIDER.acquire().await.unwrap(); - defer!(AppProxy::resume()); + let _permit = Permit::new(HIDER.acquire().await.unwrap(), AppProxy::resume()); AppProxy::stop().await; let (id, cmd) = (task.id, task.cmd.clone());