mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-25 10:56:19 +04:00
Fix system clipboard with mosh + tmux
Some times tmux doesn't pass the clipboard information to the terminal correctly. This is the case of mosh + tmux. The current clipboard doesn't work properly in this case. However, when the tmux option `allow-passthrough` is on, we can escape tmux and pass the OSC52 string directly to the terminal. In this patch, if helix detects that tmux `allow-passthrough` is on, it will use the OSC52 clipboard provider and will escape tmux and pass the OSC52 directly to the terminal. Tested with mosh + tmux with the `allow-passthrough` option on.
This commit is contained in:
parent
761f70d611
commit
64000f5875
@ -96,7 +96,39 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
|||||||
Box::new(provider::FallbackProvider::new())
|
Box::new(provider::FallbackProvider::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(windows, target_arch = "wasm32", target_os = "macos")))]
|
#[cfg(not(any(windows, target_arch = "wasm32")))]
|
||||||
|
// Check if we are in tmux and the allow-passthrough is on.
|
||||||
|
fn tmux_allow_passthrough() -> bool {
|
||||||
|
use helix_stdx::env::env_var_is_set;
|
||||||
|
|
||||||
|
if !env_var_is_set("TMUX") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
use std::process::Command;
|
||||||
|
let result = Command::new("tmux")
|
||||||
|
.arg("show")
|
||||||
|
.arg("-gw")
|
||||||
|
.arg("allow-passthrough")
|
||||||
|
.output();
|
||||||
|
let output = match result {
|
||||||
|
Ok(out) => out,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = match String::from_utf8(output.stdout) {
|
||||||
|
Ok(out) => out,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
output.contains("on")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(windows, target_os = "wasm32", target_os = "macos")))]
|
||||||
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
||||||
use helix_stdx::env::{binary_exists, env_var_is_set};
|
use helix_stdx::env::{binary_exists, env_var_is_set};
|
||||||
use provider::command::is_exit_success;
|
use provider::command::is_exit_success;
|
||||||
@ -138,7 +170,7 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
|||||||
paste => "termux-clipboard-get";
|
paste => "termux-clipboard-get";
|
||||||
copy => "termux-clipboard-set";
|
copy => "termux-clipboard-set";
|
||||||
}
|
}
|
||||||
} else if env_var_is_set("TMUX") && binary_exists("tmux") {
|
} else if env_var_is_set("TMUX") && binary_exists("tmux") && !tmux_allow_passthrough() {
|
||||||
command_provider! {
|
command_provider! {
|
||||||
paste => "tmux", "save-buffer", "-";
|
paste => "tmux", "save-buffer", "-";
|
||||||
copy => "tmux", "load-buffer", "-w", "-";
|
copy => "tmux", "load-buffer", "-w", "-";
|
||||||
@ -148,7 +180,7 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(windows))]
|
||||||
pub mod provider {
|
pub mod provider {
|
||||||
use super::{ClipboardProvider, ClipboardType};
|
use super::{ClipboardProvider, ClipboardType};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
@ -156,6 +188,7 @@ pub mod provider {
|
|||||||
|
|
||||||
#[cfg(feature = "term")]
|
#[cfg(feature = "term")]
|
||||||
mod osc52 {
|
mod osc52 {
|
||||||
|
use crate::clipboard::tmux_allow_passthrough;
|
||||||
use {super::ClipboardType, crate::base64};
|
use {super::ClipboardType, crate::base64};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -179,8 +212,14 @@ fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
|
|||||||
ClipboardType::Clipboard => "c",
|
ClipboardType::Clipboard => "c",
|
||||||
ClipboardType::Selection => "p",
|
ClipboardType::Selection => "p",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/
|
// Send an OSC 52 set command: https://terminalguide.namepad.de/seq/osc-52/
|
||||||
write!(f, "\x1b]52;{};{}\x1b\\", kind, &self.encoded_content)
|
let mut osc52 = format!("\x1b]52;{};{}\x07", kind, &self.encoded_content);
|
||||||
|
if tmux_allow_passthrough() {
|
||||||
|
// If we are inside tmux and we are allow to passthrough, escape it too.
|
||||||
|
osc52 = format!("\x1bPtmux;\x1b{}\x1b\\", osc52);
|
||||||
|
}
|
||||||
|
f.write_str(&osc52)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user