From bafb8b9a60f85f0ddf8e05343c4219a55c631825 Mon Sep 17 00:00:00 2001 From: Jayce Fayne Date: Fri, 10 Jun 2022 15:26:34 +0200 Subject: [PATCH 1/3] support copy to clipboard on wayland --- src/clipboard.rs | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/clipboard.rs b/src/clipboard.rs index a7ab23fa09..08f8305b47 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -45,21 +45,29 @@ fn gen_command( #[cfg(all(target_family = "unix", not(target_os = "macos")))] pub fn copy_string(string: &str) -> Result<()> { + use std::env; use std::path::PathBuf; use which::which; - let (path, xclip_syntax) = which("xclip").ok().map_or_else( - || { - ( - which("xsel") - .ok() - .unwrap_or_else(|| PathBuf::from("xsel")), - false, - ) - }, - |path| (path, true), - ); - - let cmd = gen_command(path, xclip_syntax); + let cmd = if env::var("WAYLAND_DISPLAY").is_ok() { + Command::new( + which("wl-copy") + .ok() + .unwrap_or_else(|| PathBuf::from("wl-copy")), + ) + } else { + let (path, xclip_syntax) = which("xclip").ok().map_or_else( + || { + ( + which("xsel") + .ok() + .unwrap_or_else(|| PathBuf::from("xsel")), + false, + ) + }, + |path| (path, true), + ); + gen_command(path, xclip_syntax) + }; execute_copy_command(cmd, string) } From f60dee581c0c96325814b2c98446d4252df49c80 Mon Sep 17 00:00:00 2001 From: Jayce Fayne Date: Fri, 10 Jun 2022 15:33:27 +0200 Subject: [PATCH 2/3] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b46553636e..aa1cda4163 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * use `GIT_DIR` and `GIT_WORK_DIR` from environment if set ([#1191](https://github.com/extrawurst/gitui/pull/1191)) * new [FAQ](./FAQ.md)s page * mention macports in install section [[@fs111](https://github.com/fs111)]([#1237](https://github.com/extrawurst/gitui/pull/1237)) +* support copy to clipboard on wayland ([#397](https://github.com/extrawurst/gitui/issues/397)) ### Fixed * opening tags list without remotes ([#1111](https://github.com/extrawurst/gitui/issues/1111)) From 0c372a2ef352fd6a79f9dbf3524fab7656313dc8 Mon Sep 17 00:00:00 2001 From: Jayce Fayne Date: Sun, 12 Jun 2022 10:18:19 +0200 Subject: [PATCH 3/3] refactor + use `which` on all platforms --- Cargo.toml | 2 -- src/clipboard.rs | 82 ++++++++++++++++++++---------------------------- 2 files changed, 34 insertions(+), 50 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ad3f1c3d7e..7a20cf12d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,8 +50,6 @@ tui = { version = "0.18", default-features = false, features = ['crossterm', 'se unicode-segmentation = "1.9" unicode-truncate = "0.2" unicode-width = "0.1" - -[target.'cfg(all(target_family="unix",not(target_os="macos")))'.dependencies] which = "4.2" # pprof is not available on windows diff --git a/src/clipboard.rs b/src/clipboard.rs index 08f8305b47..fcb6af126f 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -1,14 +1,20 @@ use anyhow::{anyhow, Result}; -#[cfg(target_family = "unix")] -#[cfg(not(target_os = "macos"))] -use std::ffi::OsStr; use std::io::Write; +use std::path::PathBuf; use std::process::{Command, Stdio}; +use which::which; -fn execute_copy_command(command: Command, text: &str) -> Result<()> { - let mut command = command; +fn exec_copy_with_args( + command: &str, + args: &[&str], + text: &str, +) -> Result<()> { + let binary = which(command) + .ok() + .unwrap_or_else(|| PathBuf::from(command)); - let mut process = command + let mut process = Command::new(binary) + .args(args) .stdin(Stdio::piped()) .stdout(Stdio::null()) .spawn() @@ -28,55 +34,35 @@ fn execute_copy_command(command: Command, text: &str) -> Result<()> { Ok(()) } -#[cfg(all(target_family = "unix", not(target_os = "macos")))] -fn gen_command( - path: impl AsRef, - xclip_syntax: bool, -) -> Command { - let mut c = Command::new(path); - if xclip_syntax { - c.arg("-selection"); - c.arg("clipboard"); - } else { - c.arg("--clipboard"); - } - c +fn exec_copy(command: &str, text: &str) -> Result<()> { + exec_copy_with_args(command, &[], text) } #[cfg(all(target_family = "unix", not(target_os = "macos")))] -pub fn copy_string(string: &str) -> Result<()> { - use std::env; - use std::path::PathBuf; - use which::which; - let cmd = if env::var("WAYLAND_DISPLAY").is_ok() { - Command::new( - which("wl-copy") - .ok() - .unwrap_or_else(|| PathBuf::from("wl-copy")), - ) - } else { - let (path, xclip_syntax) = which("xclip").ok().map_or_else( - || { - ( - which("xsel") - .ok() - .unwrap_or_else(|| PathBuf::from("xsel")), - false, - ) - }, - |path| (path, true), - ); - gen_command(path, xclip_syntax) - }; - execute_copy_command(cmd, string) +pub fn copy_string(text: &str) -> Result<()> { + if std::env::var("WAYLAND_DISPLAY").is_ok() { + return exec_copy("wl-copy", text); + } + + if exec_copy_with_args( + "xclip", + &["-selection", "clipboard"], + text, + ) + .is_err() + { + return exec_copy_with_args("xsel", &["--clipboard"], text); + } + + Ok(()) } #[cfg(target_os = "macos")] -pub fn copy_string(string: &str) -> Result<()> { - execute_copy_command(Command::new("pbcopy"), string) +pub fn copy_string(text: &str) -> Result<()> { + exec_copy("pbcopy", text) } #[cfg(windows)] -pub fn copy_string(string: &str) -> Result<()> { - execute_copy_command(Command::new("clip"), string) +pub fn copy_string(text: &str) -> Result<()> { + exec_copy("clip", text) }