From df42ca799e95055afcba79db06e329ae51136e4f Mon Sep 17 00:00:00 2001 From: sxyazi Date: Tue, 19 Dec 2023 22:43:03 +0800 Subject: [PATCH] feat: use a global clipboard --- Cargo.lock | 3 ++- yazi-core/Cargo.toml | 4 +++ .../external => yazi-core/src}/clipboard.rs | 26 +++++++++++-------- yazi-core/src/input/commands/paste.rs | 4 +-- yazi-core/src/input/input.rs | 8 +++--- yazi-core/src/lib.rs | 8 +++++- yazi-core/src/tab/commands/copy.rs | 5 ++-- yazi-scheduler/Cargo.toml | 3 --- yazi-scheduler/src/external/mod.rs | 2 -- 9 files changed, 35 insertions(+), 28 deletions(-) rename {yazi-scheduler/src/external => yazi-core/src}/clipboard.rs (83%) diff --git a/Cargo.lock b/Cargo.lock index e54063b17..c544e00d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2611,7 +2611,9 @@ name = "yazi-core" version = "0.1.5" dependencies = [ "anyhow", + "base64", "bitflags 2.4.1", + "clipboard-win", "crossterm", "futures", "indexmap", @@ -2686,7 +2688,6 @@ dependencies = [ "anyhow", "async-channel", "base64", - "clipboard-win", "crossterm", "futures", "libc", diff --git a/yazi-core/Cargo.toml b/yazi-core/Cargo.toml index 92069d800..8b083ccfa 100644 --- a/yazi-core/Cargo.toml +++ b/yazi-core/Cargo.toml @@ -16,6 +16,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.1.5" } # External dependencies anyhow = "^1" +base64 = "^0" bitflags = "^2" crossterm = "^0" futures = "^0" @@ -34,3 +35,6 @@ yazi-prebuild = "^0" # Logging tracing = { version = "^0", features = [ "max_level_debug", "release_max_level_warn" ] } + +[target."cfg(windows)".dependencies] +clipboard-win = "^4" diff --git a/yazi-scheduler/src/external/clipboard.rs b/yazi-core/src/clipboard.rs similarity index 83% rename from yazi-scheduler/src/external/clipboard.rs rename to yazi-core/src/clipboard.rs index 3708a79b9..418d85a3d 100644 --- a/yazi-scheduler/src/external/clipboard.rs +++ b/yazi-core/src/clipboard.rs @@ -1,8 +1,13 @@ use std::ffi::OsString; +use parking_lot::Mutex; +use yazi_shared::RoCell; + +pub static CLIPBOARD: RoCell = RoCell::new(); + #[derive(Default)] pub struct Clipboard { - content: OsString, + content: Mutex, } impl Clipboard { @@ -14,7 +19,7 @@ impl Clipboard { use yazi_shared::in_ssh_connection; if in_ssh_connection() { - return self.content.clone(); + return self.content.lock().clone(); } let all = [ @@ -32,7 +37,7 @@ impl Clipboard { return OsString::from_vec(output.stdout); } } - self.content.clone() + self.content.lock().clone() } #[cfg(windows)] @@ -44,20 +49,20 @@ impl Clipboard { return s.into(); } - self.content.clone() + self.content.lock().clone() } #[cfg(unix)] - pub async fn set(&mut self, s: impl AsRef) { + pub async fn set(&self, s: impl AsRef) { use std::{io::stdout, process::Stdio}; use crossterm::execute; use tokio::{io::AsyncWriteExt, process::Command}; use yazi_shared::in_ssh_connection; - self.content = s.as_ref().to_owned(); + *self.content.lock() = s.as_ref().to_owned(); if in_ssh_connection() { - execute!(stdout(), osc52::SetClipboard::new(&self.content)).ok(); + execute!(stdout(), osc52::SetClipboard::new(s.as_ref())).ok(); } let all = [ @@ -93,12 +98,12 @@ impl Clipboard { } #[cfg(windows)] - pub async fn set(&mut self, s: impl AsRef) { + pub async fn set(&self, s: impl AsRef) { use clipboard_win::{formats, set_clipboard}; - self.content = s.as_ref().to_owned(); - let s = s.as_ref().to_owned(); + *self.content.lock() = s.clone(); + tokio::task::spawn_blocking(move || set_clipboard(formats::Unicode, s.to_string_lossy())) .await .ok(); @@ -110,7 +115,6 @@ mod osc52 { use std::ffi::OsStr; use base64::{engine::general_purpose, Engine}; - use crossterm; #[derive(Debug)] pub struct SetClipboard { diff --git a/yazi-core/src/input/commands/paste.rs b/yazi-core/src/input/commands/paste.rs index be717988a..180278750 100644 --- a/yazi-core/src/input/commands/paste.rs +++ b/yazi-core/src/input/commands/paste.rs @@ -1,6 +1,6 @@ use yazi_shared::event::Exec; -use crate::input::{op::InputOp, Input}; +use crate::{input::{op::InputOp, Input}, CLIPBOARD}; pub struct Opt { before: bool, @@ -17,7 +17,7 @@ impl Input { self.handle_op(self.snap().cursor, true); } - let s = futures::executor::block_on(self.clipboard.get()); + let s = futures::executor::block_on(CLIPBOARD.get()); if s.is_empty() { return false; } diff --git a/yazi-core/src/input/input.rs b/yazi-core/src/input/input.rs index def26d513..862ac3f43 100644 --- a/yazi-core/src/input/input.rs +++ b/yazi-core/src/input/input.rs @@ -3,10 +3,10 @@ use std::ops::Range; use tokio::sync::mpsc::UnboundedSender; use unicode_width::UnicodeWidthStr; use yazi_config::{popup::Position, INPUT}; -use yazi_scheduler::external::Clipboard; use yazi_shared::InputError; use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps}; +use crate::CLIPBOARD; #[derive(Default)] pub struct Input { @@ -24,8 +24,6 @@ pub struct Input { // Shell pub(super) highlight: bool, - - pub(super) clipboard: Clipboard, } impl Input { @@ -61,7 +59,7 @@ impl Input { let drain = snap.value.drain(start.unwrap()..end.unwrap()).collect::(); if cut { - futures::executor::block_on(self.clipboard.set(&drain)); + futures::executor::block_on(CLIPBOARD.set(&drain)); } snap.op = InputOp::None; @@ -74,7 +72,7 @@ impl Input { let yanked = &snap.value[start.unwrap()..end.unwrap()]; snap.op = InputOp::None; - futures::executor::block_on(self.clipboard.set(yanked)); + futures::executor::block_on(CLIPBOARD.set(yanked)); } }; diff --git a/yazi-core/src/lib.rs b/yazi-core/src/lib.rs index 08b17e4d5..5552e2acc 100644 --- a/yazi-core/src/lib.rs +++ b/yazi-core/src/lib.rs @@ -6,6 +6,7 @@ clippy::unit_arg )] +mod clipboard; pub mod completion; mod context; pub mod files; @@ -20,8 +21,13 @@ pub mod tab; pub mod tasks; pub mod which; +pub use clipboard::*; pub use context::*; pub use highlighter::*; pub use step::*; -pub fn init() { yazi_scheduler::init(); } +pub fn init() { + CLIPBOARD.with(Default::default); + + yazi_scheduler::init(); +} diff --git a/yazi-core/src/tab/commands/copy.rs b/yazi-core/src/tab/commands/copy.rs index 05e26b877..aae06fbe6 100644 --- a/yazi-core/src/tab/commands/copy.rs +++ b/yazi-core/src/tab/commands/copy.rs @@ -1,9 +1,8 @@ use std::ffi::{OsStr, OsString}; -use yazi_scheduler::external::Clipboard; use yazi_shared::event::Exec; -use crate::tab::Tab; +use crate::{tab::Tab, CLIPBOARD}; pub struct Opt<'a> { type_: &'a str, @@ -32,7 +31,7 @@ impl Tab { } } - futures::executor::block_on(Clipboard::default().set(s)); + futures::executor::block_on(CLIPBOARD.set(s)); false } } diff --git a/yazi-scheduler/Cargo.toml b/yazi-scheduler/Cargo.toml index c839b1bb4..2a950db81 100644 --- a/yazi-scheduler/Cargo.toml +++ b/yazi-scheduler/Cargo.toml @@ -29,6 +29,3 @@ trash = "^3" # Logging tracing = { version = "^0", features = [ "max_level_debug", "release_max_level_warn" ] } - -[target."cfg(windows)".dependencies] -clipboard-win = "^4" diff --git a/yazi-scheduler/src/external/mod.rs b/yazi-scheduler/src/external/mod.rs index d354f4380..03bfe89c7 100644 --- a/yazi-scheduler/src/external/mod.rs +++ b/yazi-scheduler/src/external/mod.rs @@ -1,4 +1,3 @@ -mod clipboard; mod fd; mod ffmpegthumbnailer; mod file; @@ -11,7 +10,6 @@ mod shell; mod unar; mod zoxide; -pub use clipboard::*; pub use fd::*; pub use ffmpegthumbnailer::*; pub use file::*;