summaryrefslogtreecommitdiffstats
path: root/src/utils/clipboard.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/clipboard.rs')
-rw-r--r--src/utils/clipboard.rs72
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")
}