feat: add new bulk event kind to DDS (#937)

Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
Mika Vilpas 2024-04-25 14:18:12 +03:00 committed by sxyazi
parent 1a3565963c
commit 2febbee595
No known key found for this signature in database
4 changed files with 30 additions and 16 deletions

View File

@ -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);

View File

@ -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,
}

View File

@ -8,21 +8,27 @@ use super::Body;
#[derive(Debug, Serialize, Deserialize)]
pub struct BodyBulk<'a> {
pub tab: usize,
pub changes: Cow<'a, HashMap<Url, Url>>,
pub changes: HashMap<Cow<'a, Url>, Cow<'a, Url>>,
}
impl<'a> BodyBulk<'a> {
#[inline]
pub fn borrowed(tab: usize, changes: &'a HashMap<Url, Url>) -> 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<Url, Url>) -> 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<BodyBulk<'a>> for Body<'a> {
impl IntoLua<'_> for BodyBulk<'static> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
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<Url, Url>,
pub inner: hash_map::IntoIter<Cow<'static, Url>, 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<Self>| {
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)

View File

@ -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<RwLock<HashMap<String, HashMap<String, Function<'static>>>>> =
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<Url>) {
if LOCAL.read().contains_key("yank") {
Self::pub_(BodyYank::dummy());