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.rs61
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>,