clipboard_anywhere/
lib.rs1use std::{
2 env,
3 process::{Command, Stdio},
4};
5
6use anyhow::Result;
7use arboard::Clipboard;
8use duct::cmd;
9
10pub fn set_clipboard(text: &str) -> Result<()> {
13 if is_wsl::is_wsl() {
14 set_wsl_clipboard(text)?;
15 } else if env::var("SSH_CLIENT").is_ok() {
16 set_clipboard_osc_52(text);
18 } else {
19 match Clipboard::new() {
21 Ok(mut ctx) => {
22 if let Err(e) = ctx.set_text(text.to_string()) {
23 anyhow::bail!("Failed to set clipboard: {e}");
24 }
25 }
26 Err(e) => anyhow::bail!("Failed to create clipboard context: {e}"),
27 }
28 }
29
30 Ok(())
31}
32
33pub fn get_clipboard() -> Result<String> {
34 if is_wsl::is_wsl() {
35 let stdout = cmd!("powershell.exe", "get-clipboard").read()?;
36 Ok(stdout.trim().to_string())
37 } else if env::var("SSH_CLIENT").is_ok() {
38 anyhow::bail!("SSH clipboard not supported");
39 } else {
40 match Clipboard::new() {
42 Ok(mut ctx) => match ctx.get_text() {
43 Ok(text) => Ok(text),
44 Err(e) => anyhow::bail!("Failed to get clipboard: {e}"),
45 },
46 Err(e) => anyhow::bail!("Failed to create clipboard context: {e}"),
47 }
48 }
49}
50
51fn set_clipboard_osc_52(text: &str) {
53 print!("\x1B]52;c;{}\x07", base64::encode(text));
54}
55
56fn set_wsl_clipboard(s: &str) -> anyhow::Result<()> {
58 let escaped_s = s.replace("'", "''");
67
68 let mut powershell = Command::new("powershell.exe")
69 .arg("-NoProfile")
70 .arg("-Command")
71 .arg(&format!("Set-Clipboard -Value '{}'", escaped_s))
72 .stdout(Stdio::null())
73 .stderr(Stdio::null())
74 .spawn()?;
75
76 powershell.wait()?;
78
79 Ok(())
80}