1use anyhow::Result;
2use arboard::{Clipboard, Error};
3use std::env;
4use std::process;
5use std::sync::{Arc, Mutex};
6
7#[cfg(target_os = "linux")]
8use arboard::SetExtLinux;
9
10use crate::DAEMONIZE_ARG;
11
12pub struct EditorClipboard {
13 clipboard: Arc<Mutex<Clipboard>>,
14}
15
16impl EditorClipboard {
17 pub fn new() -> Result<EditorClipboard, Error> {
18 Clipboard::new().map(|c| EditorClipboard {
19 clipboard: Arc::new(Mutex::new(c)),
20 })
21 }
22
23 pub fn try_new() -> Option<EditorClipboard> {
24 Self::new().ok()
25 }
26
27 pub fn set_contents(&mut self, content: String) -> Result<(), Error> {
28 #[cfg(target_os = "linux")]
29 {
30 if env::args().nth(1).as_deref() == Some(DAEMONIZE_ARG) {
31 let mut clipboard = self
32 .clipboard
33 .lock()
34 .map_err(|_e| arboard::Error::ContentNotAvailable)?;
35 clipboard.set().wait().text(content)?;
36 } else {
37 process::Command::new(env::current_exe().unwrap())
38 .arg(DAEMONIZE_ARG)
39 .arg(content)
40 .stdin(process::Stdio::null())
41 .stdout(process::Stdio::null())
42 .stderr(process::Stdio::null())
43 .current_dir("/")
44 .spawn()
45 .map_err(|_e| arboard::Error::ContentNotAvailable)?;
46 }
47 }
48
49 #[cfg(not(target_os = "linux"))]
50 {
51 let mut clipboard = self.clipboard.lock().unwrap();
52 clipboard.set_text(content)?;
53 }
54
55 Ok(())
56 }
57
58 pub fn get_content(&mut self) -> Result<String, Error> {
59 let mut clipboard = self.clipboard.lock().unwrap();
60 clipboard.get_text()
61 }
62
63 #[cfg(target_os = "linux")]
64 pub fn handle_daemon_args() -> Result<(), Error> {
65 if let Some(content) = env::args().nth(2) {
66 if env::args().nth(1).as_deref() == Some(DAEMONIZE_ARG) {
67 let mut clipboard = Self::new()?;
68 clipboard.set_contents(content)?;
69 std::process::exit(0);
70 }
71 }
72 Ok(())
73 }
74}