use std::io::Write;
use std::process::{Command, Stdio};
use base64::{Engine as _, engine::general_purpose::STANDARD};
pub fn copy(text: &str) -> bool {
if try_system_tool(text) {
return true;
}
if osc52_copy(text).is_ok() {
return true;
}
false
}
fn try_system_tool(text: &str) -> bool {
let candidates: &[(&str, &[&str])] = &[
("wl-copy", &[]),
("xclip", &["-selection", "clipboard"]),
("xsel", &["--clipboard", "--input"]),
("pbcopy", &[]),
];
for (cmd, args) in candidates {
if let Ok(mut child) = Command::new(cmd)
.args(*args)
.stdin(Stdio::piped())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
{
if let Some(mut stdin) = child.stdin.take() {
if stdin.write_all(text.as_bytes()).is_ok() {
drop(stdin);
if child.wait().map(|s| s.success()).unwrap_or(false) {
return true;
}
}
}
}
}
false
}
fn osc52_copy(text: &str) -> std::io::Result<()> {
let encoded = STANDARD.encode(text.as_bytes());
let seq = format!("\x1b]52;c;{}\x07", encoded);
let mut stdout = std::io::stdout();
stdout.write_all(seq.as_bytes())?;
stdout.flush()?;
Ok(())
}