diff --git a/yazi-core/src/manager/commands/bulk_rename.rs b/yazi-core/src/manager/commands/bulk_rename.rs index e3b65244..b7f630e5 100644 --- a/yazi-core/src/manager/commands/bulk_rename.rs +++ b/yazi-core/src/manager/commands/bulk_rename.rs @@ -4,6 +4,7 @@ use anyhow::{anyhow, Result}; use scopeguard::defer; use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}}; use yazi_config::{OPEN, PREVIEW}; +use yazi_dds::Pubsub; use yazi_proxy::{AppProxy, TasksProxy, HIDER, WATCHER}; use yazi_shared::{fs::{accessible, max_common_root, File, FilesOp, Url}, term::Term}; @@ -95,6 +96,7 @@ impl Manager { } if !succeeded.is_empty() { + Pubsub::pub_from_bulk(succeeded.iter().map(|(u, f)| (u, &f.url)).collect()); FilesOp::Upserting(cwd, succeeded).emit(); } drop(permit); diff --git a/yazi-dds/src/body/body.rs b/yazi-dds/src/body/body.rs index 718ff4b3..ee812521 100644 --- a/yazi-dds/src/body/body.rs +++ b/yazi-dds/src/body/body.rs @@ -54,7 +54,6 @@ impl Body<'static> { match Self::from_str(kind, body) { Ok(Self::Cd(b)) => b.tab, Ok(Self::Hover(b)) => b.tab, - Ok(Self::Bulk(b)) => b.tab, Ok(Self::Rename(b)) => b.tab, _ => 0, } diff --git a/yazi-dds/src/body/bulk.rs b/yazi-dds/src/body/bulk.rs index 4e35f1cc..47c8840a 100644 --- a/yazi-dds/src/body/bulk.rs +++ b/yazi-dds/src/body/bulk.rs @@ -8,21 +8,27 @@ use super::Body; #[derive(Debug, Serialize, Deserialize)] pub struct BodyBulk<'a> { - pub tab: usize, - pub changes: Cow<'a, HashMap>, + pub changes: HashMap, Cow<'a, Url>>, } impl<'a> BodyBulk<'a> { #[inline] - pub fn borrowed(tab: usize, changes: &'a HashMap) -> Body<'a> { - Self { tab, changes: Cow::Borrowed(changes) }.into() + pub fn borrowed(changes: &HashMap<&'a Url, &'a Url>) -> Body<'a> { + let iter = changes.iter().map(|(&from, &to)| (Cow::Borrowed(from), Cow::Borrowed(to))); + + Self { changes: iter.collect() }.into() } } impl BodyBulk<'static> { #[inline] - pub fn owned(tab: usize, changes: &HashMap) -> Body<'static> { - Self { tab, changes: Cow::Owned(changes.clone()) }.into() + pub fn owned(changes: &HashMap<&Url, &Url>) -> Body<'static> { + let changes = changes + .iter() + .map(|(&from, &to)| (Cow::Owned(from.clone()), Cow::Owned(to.clone()))) + .collect(); + + Self { changes }.into() } } @@ -32,27 +38,22 @@ impl<'a> From> for Body<'a> { impl IntoLua<'_> for BodyBulk<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { - BodyBulkIter { tab: self.tab, inner: self.changes.into_owned().into_iter() }.into_lua(lua) + BodyBulkIter { inner: self.changes.into_iter() }.into_lua(lua) } } // --- Iterator pub struct BodyBulkIter { - pub tab: usize, - pub inner: hash_map::IntoIter, + pub inner: hash_map::IntoIter, Cow<'static, Url>>, } impl UserData for BodyBulkIter { - fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { - fields.add_field_method_get("tab", |_, me| Ok(me.tab)); - } - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.inner.len())); methods.add_meta_function(MetaMethod::Pairs, |lua, me: AnyUserData| { let iter = lua.create_function(|lua, mut me: UserDataRefMut| { - if let Some((from, to)) = me.inner.next() { + if let Some((Cow::Owned(from), Cow::Owned(to))) = me.inner.next() { (lua.create_any_userdata(from)?, lua.create_any_userdata(to)?).into_lua_multi(lua) } else { ().into_lua_multi(lua) diff --git a/yazi-dds/src/pubsub.rs b/yazi-dds/src/pubsub.rs index 698a9ea4..61f7230c 100644 --- a/yazi-dds/src/pubsub.rs +++ b/yazi-dds/src/pubsub.rs @@ -5,7 +5,7 @@ use parking_lot::RwLock; use yazi_boot::BOOT; use yazi_shared::{fs::Url, RoCell}; -use crate::{body::{Body, BodyCd, BodyDelete, BodyHi, BodyHover, BodyMove, BodyMoveItem, BodyRename, BodyTrash, BodyYank}, Client, ID, PEERS}; +use crate::{body::{Body, BodyBulk, BodyCd, BodyDelete, BodyHi, BodyHover, BodyMove, BodyMoveItem, BodyRename, BodyTrash, BodyYank}, Client, ID, PEERS}; pub static LOCAL: RoCell>>>> = RoCell::new(); @@ -130,6 +130,18 @@ impl Pubsub { } } + pub fn pub_from_bulk(changes: HashMap<&Url, &Url>) { + if LOCAL.read().contains_key("bulk") { + Self::pub_(BodyBulk::owned(&changes)); + } + if PEERS.read().values().any(|p| p.able("bulk")) { + Client::push(BodyBulk::borrowed(&changes)); + } + if BOOT.local_events.contains("bulk") { + BodyBulk::borrowed(&changes).with_receiver(*ID).flush(); + } + } + pub fn pub_from_yank(cut: bool, urls: &HashSet) { if LOCAL.read().contains_key("yank") { Self::pub_(BodyYank::dummy());