Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-view/src/clipboard.rs')
| -rw-r--r-- | helix-view/src/clipboard.rs | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index 2641d98f..5e16461e 100644 --- a/helix-view/src/clipboard.rs +++ b/helix-view/src/clipboard.rs @@ -122,11 +122,10 @@ mod external { Self::Tmux } else if binary_exists("pbcopy") && binary_exists("pbpaste") { Self::Pasteboard + } else if cfg!(feature = "term") { + Self::Termcode } else { - #[cfg(feature = "term")] - return Self::Termcode; - #[cfg(not(feature = "term"))] - return Self::None; + Self::None } } @@ -193,7 +192,7 @@ mod external { Self::Wayland => builtin_name("wayland", &WL_CLIPBOARD), Self::XClip => builtin_name("x-clip", &XCLIP), Self::XSel => builtin_name("x-sel", &XSEL), - Self::Win32Yank => builtin_name("win32-yank", &WIN32), + Self::Win32Yank => builtin_name("win-32-yank", &WIN32), Self::Tmux => builtin_name("tmux", &TMUX), Self::Termux => builtin_name("termux", &TERMUX), #[cfg(windows)] @@ -292,17 +291,10 @@ mod external { }, #[cfg(feature = "term")] Self::Termcode => { - use std::io::Write; - use termina::escape::osc::{self, Osc}; - let selection = match clipboard_type { - ClipboardType::Clipboard => osc::Selection::CLIPBOARD, - ClipboardType::Selection => osc::Selection::PRIMARY, - }; - // NOTE: it would be ideal to have the terminal execute this but it _should_ - // work to send this over stdout instead. - let mut stdout = std::io::stdout().lock(); - write!(stdout, "{}", Osc::SetSelection(selection, content))?; - stdout.flush()?; + crossterm::queue!( + std::io::stdout(), + osc52::SetClipboardCommand::new(content, clipboard_type) + )?; Ok(()) } Self::Custom(command_provider) => match clipboard_type { @@ -407,6 +399,43 @@ mod external { paste => "termux-clipboard-set"; } + #[cfg(feature = "term")] + mod osc52 { + use {super::ClipboardType, crate::base64}; + + pub struct SetClipboardCommand { + encoded_content: String, + clipboard_type: ClipboardType, + } + + impl SetClipboardCommand { + pub fn new(content: &str, clipboard_type: ClipboardType) -> Self { + Self { + encoded_content: base64::encode(content.as_bytes()), + clipboard_type, + } + } + } + + impl crossterm::Command for SetClipboardCommand { + fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result { + let kind = match &self.clipboard_type { + ClipboardType::Clipboard => "c", + ClipboardType::Selection => "p", + }; + // Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/ + write!(f, "\x1b]52;{};{}\x1b\\", kind, &self.encoded_content) + } + #[cfg(windows)] + fn execute_winapi(&self) -> std::result::Result<(), std::io::Error> { + Err(std::io::Error::new( + std::io::ErrorKind::Other, + "OSC clipboard codes not supported by winapi.", + )) + } + } + } + fn execute_command( cmd: &Command, input: Option<&str>, |