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 | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index 2641d98f..1cf63348 100644 --- a/helix-view/src/clipboard.rs +++ b/helix-view/src/clipboard.rs @@ -193,7 +193,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 +292,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 +400,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>, |