diff --git a/yazi-core/src/manager/commands/paste.rs b/yazi-core/src/manager/commands/paste.rs index f551f023..876196cd 100644 --- a/yazi-core/src/manager/commands/paste.rs +++ b/yazi-core/src/manager/commands/paste.rs @@ -1,9 +1,10 @@ +use yazi_dds::Pubsub; use yazi_shared::event::Cmd; use crate::{manager::Manager, tasks::Tasks}; pub struct Opt { - force: bool, + force: bool, follow: bool, } @@ -21,6 +22,12 @@ impl Manager { if self.yanked.cut { tasks.file_cut(&src, dest, opt.force); + src.iter().for_each(|source_file| { + if let Some(name) = source_file.file_name().map(|s| dest.join(s)) { + Pubsub::pub_from_move(self.tabs.cursor, source_file, &name); + } + }); + self.tabs.iter_mut().for_each(|t| _ = t.selected.remove_many(&src, false)); self.unyank(()); } else { diff --git a/yazi-dds/src/body/body.rs b/yazi-dds/src/body/body.rs index 693d987b..33cf0f3d 100644 --- a/yazi-dds/src/body/body.rs +++ b/yazi-dds/src/body/body.rs @@ -2,7 +2,9 @@ use anyhow::Result; use mlua::{ExternalResult, IntoLua, Lua, Value}; use serde::Serialize; -use super::{BodyBulk, BodyCd, BodyCustom, BodyHey, BodyHi, BodyHover, BodyRename, BodyYank}; +use super::{ + BodyBulk, BodyCd, BodyCustom, BodyHey, BodyHi, BodyHover, BodyMove, BodyRename, BodyYank, +}; use crate::Payload; #[derive(Debug, Serialize)] @@ -13,6 +15,7 @@ pub enum Body<'a> { Cd(BodyCd<'a>), Hover(BodyHover<'a>), Rename(BodyRename<'a>), + Move(BodyMove<'a>), Bulk(BodyBulk<'a>), Yank(BodyYank<'a>), Custom(BodyCustom), @@ -52,6 +55,7 @@ impl<'a> Body<'a> { Self::Cd(_) => "cd", Self::Hover(_) => "hover", Self::Rename(_) => "rename", + Body::Move(_) => "move", Self::Bulk(_) => "bulk", Self::Yank(_) => "yank", Self::Custom(b) => b.kind.as_str(), @@ -92,6 +96,7 @@ impl IntoLua<'_> for Body<'static> { Body::Cd(b) => b.into_lua(lua), Body::Hover(b) => b.into_lua(lua), Body::Rename(b) => b.into_lua(lua), + Body::Move(b) => b.into_lua(lua), Body::Bulk(b) => b.into_lua(lua), Body::Yank(b) => b.into_lua(lua), Body::Custom(b) => b.into_lua(lua), diff --git a/yazi-dds/src/body/mod.rs b/yazi-dds/src/body/mod.rs index 4570acd4..9ce291c1 100644 --- a/yazi-dds/src/body/mod.rs +++ b/yazi-dds/src/body/mod.rs @@ -7,6 +7,7 @@ mod custom; mod hey; mod hi; mod hover; +mod move_event; mod rename; mod yank; @@ -17,5 +18,6 @@ pub use custom::*; pub use hey::*; pub use hi::*; pub use hover::*; +pub use move_event::*; pub use rename::*; pub use yank::*; diff --git a/yazi-dds/src/body/move_event.rs b/yazi-dds/src/body/move_event.rs new file mode 100644 index 00000000..64188240 --- /dev/null +++ b/yazi-dds/src/body/move_event.rs @@ -0,0 +1,46 @@ +use std::borrow::Cow; + +use mlua::{IntoLua, Lua, Value}; +use serde::{Deserialize, Serialize}; +use yazi_shared::fs::Url; + +use super::Body; + +#[derive(Debug, Serialize, Deserialize)] +pub struct BodyMove<'a> { + pub tab: usize, + pub from: Cow<'a, Url>, + pub to: Cow<'a, Url>, +} + +impl<'a> BodyMove<'a> { + #[inline] + pub fn borrowed(tab: usize, from: &'a Url, to: &'a Url) -> Body<'a> { + Self { tab, from: Cow::Borrowed(from), to: Cow::Borrowed(to) }.into() + } +} + +impl BodyMove<'static> { + #[inline] + pub fn dummy(tab: usize, from: &Url, to: &Url) -> Body<'static> { + Self { tab, from: Cow::Owned(from.clone()), to: Cow::Owned(to.clone()) }.into() + } +} + +impl<'a> From> for Body<'a> { + fn from(value: BodyMove<'a>) -> Self { + Self::Move(value) + } +} + +impl IntoLua<'_> for BodyMove<'static> { + fn into_lua(self, lua: &Lua) -> mlua::Result { + lua + .create_table_from([ + ("tab", self.tab.into_lua(lua)?), + ("from", lua.create_any_userdata(self.from.into_owned())?.into_lua(lua)?), + ("to", lua.create_any_userdata(self.to.into_owned())?.into_lua(lua)?), + ])? + .into_lua(lua) + } +} diff --git a/yazi-dds/src/payload.rs b/yazi-dds/src/payload.rs index e65b3c8f..8d4d8638 100644 --- a/yazi-dds/src/payload.rs +++ b/yazi-dds/src/payload.rs @@ -9,14 +9,18 @@ use crate::{body::Body, ID}; #[derive(Debug)] pub struct Payload<'a> { pub receiver: u64, - pub sender: u64, - pub body: Body<'a>, + pub sender: u64, + pub body: Body<'a>, } impl<'a> Payload<'a> { - pub(super) fn new(body: Body<'a>) -> Self { Self { receiver: 0, sender: *ID, body } } + pub(super) fn new(body: Body<'a>) -> Self { + Self { receiver: 0, sender: *ID, body } + } - pub(super) fn flush(&self) { writeln!(std::io::stdout(), "{self}").ok(); } + pub(super) fn flush(&self) { + writeln!(std::io::stdout(), "{self}").ok(); + } pub(super) fn try_flush(&self) { let b = if self.receiver == 0 { @@ -71,7 +75,9 @@ impl FromStr for Payload<'_> { } impl<'a> From> for Payload<'a> { - fn from(value: Body<'a>) -> Self { Self::new(value) } + fn from(value: Body<'a>) -> Self { + Self::new(value) + } } impl Display for Payload<'_> { @@ -82,6 +88,7 @@ impl Display for Payload<'_> { Body::Cd(b) => serde_json::to_string(b), Body::Hover(b) => serde_json::to_string(b), Body::Rename(b) => serde_json::to_string(b), + Body::Move(b) => serde_json::to_string(b), Body::Bulk(b) => serde_json::to_string(b), Body::Yank(b) => serde_json::to_string(b), Body::Custom(b) => serde_json::to_string(b), diff --git a/yazi-dds/src/pubsub.rs b/yazi-dds/src/pubsub.rs index 11d47c03..76c76e04 100644 --- a/yazi-dds/src/pubsub.rs +++ b/yazi-dds/src/pubsub.rs @@ -5,7 +5,10 @@ use parking_lot::RwLock; use yazi_boot::BOOT; use yazi_shared::{fs::Url, RoCell}; -use crate::{body::{Body, BodyCd, BodyHi, BodyHover, BodyRename, BodyYank}, Client, ID, PEERS}; +use crate::{ + body::{Body, BodyCd, BodyHi, BodyHover, BodyMove, BodyRename, BodyYank}, + Client, ID, PEERS, +}; pub static LOCAL: RoCell>>>> = RoCell::new(); @@ -59,13 +62,17 @@ impl Pubsub { sub!(REMOTE)(plugin, kind, f) && Self::pub_from_hi() } - pub fn unsub(plugin: &str, kind: &str) -> bool { unsub!(LOCAL)(plugin, kind) } + pub fn unsub(plugin: &str, kind: &str) -> bool { + unsub!(LOCAL)(plugin, kind) + } pub fn unsub_remote(plugin: &str, kind: &str) -> bool { unsub!(REMOTE)(plugin, kind) && Self::pub_from_hi() } - pub fn pub_(body: Body<'static>) { body.with_receiver(*ID).emit(); } + pub fn pub_(body: Body<'static>) { + body.with_receiver(*ID).emit(); + } pub fn pub_to(receiver: u64, body: Body<'static>) { if receiver == *ID { @@ -142,4 +149,16 @@ impl Pubsub { BodyYank::borrowed(cut, urls).with_receiver(*ID).flush(); } } + + pub fn pub_from_move(tab: usize, from: &Url, to: &Url) { + if LOCAL.read().contains_key("move") { + Self::pub_(BodyMove::dummy(tab, from, to)); + } + if PEERS.read().values().any(|p| p.able("move")) { + Client::push(BodyMove::borrowed(tab, from, to)); + } + if BOOT.local_events.contains("move") { + BodyMove::borrowed(tab, from, to).with_receiver(*ID).flush(); + } + } }