From 19350903e897854c36d4dd3ce59cb410dcae1a3d 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 | 62 +++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/helix-view/src/clipboard.rs b/helix-view/src/clipboard.rs index 7da65b3eba6cc..6835243e931cf 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 { @@ -194,28 +223,13 @@ 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,