diff options
Diffstat (limited to 'src/utils/clipboard.rs')
| -rw-r--r-- | src/utils/clipboard.rs | 72 |
1 files changed, 38 insertions, 34 deletions
diff --git a/src/utils/clipboard.rs b/src/utils/clipboard.rs index 6b87ff7..2361d9f 100644 --- a/src/utils/clipboard.rs +++ b/src/utils/clipboard.rs @@ -1,45 +1,49 @@ -use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _}; +use anyhow::Context; #[cfg(not(any(target_os = "android", target_os = "emscripten")))] -static CLIPBOARD: std::sync::LazyLock<std::sync::Mutex<Option<arboard::Clipboard>>> = - std::sync::LazyLock::new(|| std::sync::Mutex::new(arboard::Clipboard::new().ok())); +mod internal { + use arboard::Clipboard; + use base64::{engine::general_purpose::STANDARD, Engine as _}; + use std::sync::{LazyLock, Mutex}; -/// Attempts to set text to clipboard with OSC52 escape sequence -/// Works in many modern terminals, including over SSH. -fn set_text_osc52(text: &str) -> anyhow::Result<()> { - let encoded = BASE64.encode(text); - let seq = format!("\x1b]52;c;{encoded}\x07"); - // Write to stdout: - if let Err(e) = std::io::Write::write_all(&mut std::io::stdout(), seq.as_bytes()) { - return Err(anyhow::anyhow!("Failed to send OSC52 sequence").context(e)); - } - // Flush stdout: - if let Err(e) = std::io::Write::flush(&mut std::io::stdout()) { - return Err(anyhow::anyhow!("Failed to flush OSC52 sequence").context(e)); - } - Ok(()) -} + static CLIPBOARD: LazyLock<Mutex<Option<Clipboard>>> = + LazyLock::new(|| Mutex::new(Clipboard::new().ok())); -#[cfg(not(any(target_os = "android", target_os = "emscripten")))] -pub fn set_text(text: &str) -> anyhow::Result<()> { - // First try arboard: - let mut clipboard = CLIPBOARD.lock().unwrap(); - if let Some(clipboard) = clipboard.as_mut() { - if let Ok(()) = clipboard.set_text(text) { - #[cfg(target_os = "linux")] - std::thread::sleep(std::time::Duration::from_millis(50)); - return Ok(()); + pub fn set_text(text: &str) -> anyhow::Result<()> { + let mut clipboard = CLIPBOARD.lock().unwrap(); + match clipboard.as_mut() { + Some(clipboard) => { + clipboard.set_text(text)?; + #[cfg(target_os = "linux")] + std::thread::sleep(std::time::Duration::from_millis(50)); + Ok(()) + } + None => set_text_osc52(text), } } - // If arboard failed, try OSC52: - match set_text_osc52(text) { - Ok(()) => Ok(()), - Err(osc_err) => Err(anyhow::anyhow!("No clipboard available") - .context(format!("Failed to copy (OSC52 error: {osc_err})"))), + + /// Attempts to set text to clipboard with OSC52 escape sequence + /// Works in many modern terminals, including over SSH. + fn set_text_osc52(text: &str) -> anyhow::Result<()> { + let encoded = STANDARD.encode(text); + let seq = format!("\x1b]52;c;{encoded}\x07"); + if let Err(e) = std::io::Write::write_all(&mut std::io::stdout(), seq.as_bytes()) { + return Err(anyhow::anyhow!("Failed to send OSC52 sequence").context(e)); + } + if let Err(e) = std::io::Write::flush(&mut std::io::stdout()) { + return Err(anyhow::anyhow!("Failed to flush OSC52 sequence").context(e)); + } + Ok(()) } } #[cfg(any(target_os = "android", target_os = "emscripten"))] -pub fn set_text(_text: &str) -> anyhow::Result<()> { - Err(anyhow::anyhow!("No clipboard available").context("Failed to copy")) +mod internal { + pub fn set_text(_text: &str) -> anyhow::Result<()> { + Err(anyhow::anyhow!("No clipboard available")) + } +} + +pub fn set_text(text: &str) -> anyhow::Result<()> { + internal::set_text(text).context("Failed to copy") } |
