From 07102115c6ed682bbf66335c575f8a6ba2beb2fa Mon Sep 17 00:00:00 2001 From: Charlie Groves Date: Mon, 1 Aug 2022 07:10:02 -0400 Subject: [PATCH] Extract clipboard setting into a crossterm command --- helix-view/src/clipboard.rs | 60 ++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index 7da65b3eba6cc..7c4724e433cb8 100644 --- a/helix-view/src/clipboard.rs +++ b/helix-view/src/clipboard.rs @@ -3,6 +3,7 @@ use anyhow::Result; use std::borrow::Cow; +#[derive(Clone, Copy, Debug)] pub enum ClipboardType { Clipboard, Selection, @@ -145,6 +146,37 @@ mod provider { use anyhow::Result; use std::borrow::Cow; + #[cfg(feature = "term")] + mod osc52 { + use {super::ClipboardType, base64, crossterm}; + + #[derive(Debug)] + 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), + 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) + } + } + } + #[derive(Debug)] pub struct FallbackProvider { buf: String, @@ -168,9 +200,6 @@ mod provider { } } - #[cfg(feature = "term")] - use {base64, crossterm, std::io::stdout}; - impl ClipboardProvider for FallbackProvider { #[cfg(feature = "term")] fn name(&self) -> Cow { @@ -182,6 +211,7 @@ mod provider { Cow::Borrowed("none") } + fn get_contents(&self, clipboard_type: ClipboardType) -> Result { // This is the same noop if term is enabled or not. // We don't use the get side of OSC 52 as it isn't often enabled, it's a security hole, @@ -194,28 +224,10 @@ mod provider { Ok(value) } - #[cfg(feature = "term")] - fn set_contents(&mut self, content: String, clipboard_type: ClipboardType) -> Result<()> { - let encoded = base64::encode(&content); - let kind = match clipboard_type { - ClipboardType::Clipboard => { - // Still set our internal variables to use in get_content - self.buf = content; - "c" - } - ClipboardType::Selection => { - self.primary_buf = content; - "p" - } - }; - // Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/ - let cmd = crossterm::style::Print(format!("\x1b]52;{};{}\x1b\\", kind, encoded)); - crossterm::execute!(stdout(), cmd)?; - Ok(()) - } - - #[cfg(not(feature = "term"))] fn set_contents(&mut self, content: String, clipboard_type: ClipboardType) -> Result<()> { + #[cfg(feature = "term")] + crossterm::execute!(std::io::stdout(), osc52::SetClipboardCommand::new(&content, clipboard_type))?; + // Set our internal variables to use in get_content regardless of using OSC 52 match clipboard_type { ClipboardType::Clipboard => self.buf = content, ClipboardType::Selection => self.primary_buf = content,