From 8c0ca4c64962c593de15a7a96bf14ecdce235a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Sun, 20 Aug 2023 08:24:41 +0800 Subject: [PATCH] feat: windows clipboard support (#75) --- Cargo.lock | 28 ++++++++++++++++++++++++ core/Cargo.toml | 3 +++ core/src/external/clipboard.rs | 40 ++++++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index abe6ce57..c55379bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -316,6 +316,17 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +[[package]] +name = "clipboard-win" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -365,6 +376,7 @@ dependencies = [ "adaptor", "anyhow", "async-channel", + "clipboard-win", "config", "crossterm 0.27.0", "futures", @@ -569,6 +581,16 @@ dependencies = [ "libc", ] +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1695,6 +1717,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + [[package]] name = "strsim" version = "0.10.0" diff --git a/core/Cargo.toml b/core/Cargo.toml index f29f9bef..f7633328 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -25,3 +25,6 @@ tracing = "^0" trash = "^3" unicode-width = "^0" yazi-prebuild = "^0" + +[target.'cfg(target_os = "windows")'.dependencies] +clipboard-win = "^4" diff --git a/core/src/external/clipboard.rs b/core/src/external/clipboard.rs index ca8d5f20..59a7b8b7 100644 --- a/core/src/external/clipboard.rs +++ b/core/src/external/clipboard.rs @@ -1,9 +1,14 @@ -use std::{ffi::{OsStr, OsString}, os::unix::prelude::{OsStrExt, OsStringExt}, process::Stdio}; +use std::ffi::OsString; -use anyhow::{bail, Result}; -use tokio::{io::AsyncWriteExt, process::Command}; +use anyhow::Result; +#[cfg(not(target_os = "windows"))] pub async fn clipboard_get() -> Result { + use std::os::unix::prelude::OsStringExt; + + use anyhow::bail; + use tokio::process::Command; + let all = [ ("pbpaste", vec![]), ("wl-paste", vec![]), @@ -23,7 +28,22 @@ pub async fn clipboard_get() -> Result { bail!("failed to get clipboard") } -pub async fn clipboard_set(s: impl AsRef) -> Result<()> { +#[cfg(target_os = "windows")] +pub async fn clipboard_get() -> Result { + use anyhow::anyhow; + use clipboard_win::{formats, get_clipboard}; + + let result = tokio::task::spawn_blocking(|| get_clipboard::(formats::Unicode)); + Ok(result.await?.map_err(|_| anyhow!("failed to get clipboard"))?.into()) +} + +#[cfg(not(target_os = "windows"))] +pub async fn clipboard_set(s: impl AsRef) -> Result<()> { + use std::{os::unix::prelude::OsStrExt, process::Stdio}; + + use anyhow::bail; + use tokio::{io::AsyncWriteExt, process::Command}; + let all = [ ("pbcopy", vec![]), ("wl-copy", vec![]), @@ -55,3 +75,15 @@ pub async fn clipboard_set(s: impl AsRef) -> Result<()> { bail!("failed to set clipboard") } + +#[cfg(target_os = "windows")] +pub async fn clipboard_set(s: impl AsRef) -> Result<()> { + use anyhow::anyhow; + use clipboard_win::{formats, set_clipboard}; + + let s = s.as_ref().to_owned(); + let result = + tokio::task::spawn_blocking(move || set_clipboard(formats::Unicode, s.to_string_lossy())); + + Ok(result.await?.map_err(|_| anyhow!("failed to set clipboard"))?) +}