Skip to content

Commit

Permalink
Sync tmux clipboard and system clipboard
Browse files Browse the repository at this point in the history
When copying, also write the content into the system clipboard.
When pasting, request tmux to refresh its paste buffer from the system
clipboard, wait for the update to propagate and the request the
clipboard content from tmux.

With `set -g set-clipboard on` in tmux, this enables sharing the
system clipboard with a helix running in tmux, running in an ssh
session, running in alacritty.

The need for a wait is unfortunate, but I didn't find a better way.
Tmux asks the terminal for the clipboard content and updates its buffer
after it got an answer. The answer may come or may not. It may take
long, e.g. when running through a slow ssh connection.

The feature works well on alacritty. On konsole, it doesn't do
anything, but doesn't harm either. On xterm, `tmux refresh-client -l`
prints gibberish for me, also without using helix, so I added an
option to disable this feature.
  • Loading branch information
Flakebi committed Jun 19, 2022
1 parent ad15e7b commit 43148b4
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 8 deletions.
1 change: 1 addition & 0 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ hidden = false
| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` |
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
| `auto-info` | Whether to display infoboxes | `true` |
| `tmux-system-clipboard` | Sync with the system clipboard when running in tmux. | `true` |
| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` |
| `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file. | `[]` |

Expand Down
24 changes: 17 additions & 7 deletions helix-view/src/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use anyhow::Result;
use std::borrow::Cow;

use crate::editor::Config;

pub enum ClipboardType {
Clipboard,
Selection,
Expand Down Expand Up @@ -58,12 +60,12 @@ macro_rules! command_provider {
}

#[cfg(windows)]
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
pub fn get_clipboard_provider(_: &Config) -> Box<dyn ClipboardProvider> {
Box::new(provider::WindowsProvider::default())
}

#[cfg(target_os = "macos")]
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
pub fn get_clipboard_provider(_: &Config) -> Box<dyn ClipboardProvider> {
use provider::command::exists;

if exists("pbcopy") && exists("pbpaste") {
Expand All @@ -77,13 +79,13 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
}

#[cfg(target_os = "wasm32")]
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
pub fn get_clipboard_provider(_: &Config) -> Box<dyn ClipboardProvider> {
// TODO:
Box::new(provider::NopProvider::new())
}

#[cfg(not(any(windows, target_os = "wasm32", target_os = "macos")))]
pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
pub fn get_clipboard_provider(config: &Config) -> Box<dyn ClipboardProvider> {
use provider::command::{env_var_is_set, exists, is_exit_success};
// TODO: support for user-defined provider, probably when we have plugin support by setting a
// variable?
Expand Down Expand Up @@ -122,9 +124,17 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
copy => "termux-clipboard-set";
}
} else if env_var_is_set("TMUX") && exists("tmux") {
command_provider! {
paste => "tmux", "save-buffer", "-";
copy => "tmux", "load-buffer", "-";
if config.tmux_system_clipboard {
command_provider! {
// Refresh tmux clipboard, wait a bit for it to be updated and paste it
paste => "sh", "-c", "tmux refresh-client -l; sleep 0.1; tmux save-buffer -";
copy => "tmux", "load-buffer", "-w", "-";
}
} else {
command_provider! {
paste => "tmux", "save-buffer", "-";
copy => "tmux", "load-buffer", "-";
}
}
} else {
Box::new(provider::NopProvider::new())
Expand Down
5 changes: 4 additions & 1 deletion helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ pub struct Config {
pub file_picker: FilePickerConfig,
/// Shape for cursor in each mode
pub cursor_shape: CursorShapeConfig,
/// Sync with the system clipboard when running in tmux. Defaults to `true`.
pub tmux_system_clipboard: bool,
/// Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. Defaults to `false`.
pub true_color: bool,
/// Search configuration.
Expand Down Expand Up @@ -386,6 +388,7 @@ impl Default for Config {
auto_info: true,
file_picker: FilePickerConfig::default(),
cursor_shape: CursorShapeConfig::default(),
tmux_system_clipboard: true,
true_color: false,
search: SearchConfig::default(),
lsp: LspConfig::default(),
Expand Down Expand Up @@ -517,7 +520,7 @@ impl Editor {
syn_loader,
theme_loader,
registers: Registers::default(),
clipboard_provider: get_clipboard_provider(),
clipboard_provider: get_clipboard_provider(&*conf),
status_msg: None,
autoinfo: None,
idle_timer: Box::pin(sleep(conf.idle_timeout)),
Expand Down

0 comments on commit 43148b4

Please sign in to comment.