zyedidia / micro

A modern and intuitive terminal-based text editor
https://micro-editor.github.io
MIT License
25.04k stars 1.17k forks source link

"no clipboard received from terminal" in tmux; OSC52 works in tmux and outside of micro #3473

Open ToxicFrog opened 1 month ago

ToxicFrog commented 1 month ago

Background

I'm running Kitty as the terminal emulator, with micro installed on both the local and remote machine. Kitty's clipboard_control is set to write-clipboard write-primary read-clipboard read-primary. Tmux has set-clipboard on enabled. Micro is invoked with micro -clipboard terminal.

Description of the problem or steps to reproduce

Micro on its own works fine, with copy and paste setting and reading from the system clipboard, whether micro is running locally or over ssh.

Similarly, tmux on its own appears to be working properly, with OSC52 writes setting both the tmux and system clipboard, and OSC52 reads returning the tmux clipboard.

The problems only arise when the two are used in conjunction.

micro behaviour

Not much to say here; running locally or over ssh, as long as tmux is not involved, copy-paste works fine with micro -clipboard terminal. Anything copied in micro with ^C appears in the system clipboard, and anything in the system clipboard, whether it came from micro or not, can be pasted with ^V.

tmux behaviour

Before combining them, let's check that OSC52 is working as expected in tmux:

$ echo $TERM
tmux-256color
$ printf '\e]52;;%s\a' "$(echo $TERM | base64)"
$ printf '\e]52;;?\a'; read -e -d $'\a'
^[]52;;dG11eC0yNTZjb2xvcgo=^G

^V in a local (X-based) editor confirms that the system clipboard was also set. So both reading and writing the clipboard using OSC52 is working in tmux.

micro behaviour in tmux

Copying in micro works fine. Continuing from the previous test:

$ printf '\e]52;;?\a'; read -e -d $'\a'
^[]52;;dG11eC0yNTZjb2xvcgo=^G
$ micro -clipboard terminal
[within micro, I write out some text, copy it with ^C, and then exit without saving]
$ printf '\e]52;;?\a'; read -e -d $'\a'
^[]52;;dGhpcyBpcyBhIHRlc3QgZnJvbSBpbnNpZGUgbWljcm8=^G

So we can see here that the selection from micro was properly sent to tmux (which I confirmed copied it to my system clipboard), and subsequently asking tmux for it, even after micro has exited, works as expected.

Any attempt to paste inside micro, however, results in a No clipboard received from terminal error at the bottom of the screen.

OSC52 handling differences between tmux and kitty

While both programs support OSC52, they have two key differences in implementation. Here's the same test as above, but with Kitty:

$ printf '\e]52;;%s\a' "$(echo $TERM | base64)"
$ printf '\e]52;;?\a'; read -e -d $'\a'
^[]52;c;eHRlcm0ta2l0dHkK^[\

Note that:

Based on this, my suspicion is that micro is treating the first argument as mandatory, and is confused when tmux doesn't send it; I have not, however, verified this.

Specifications

Commit hash: v2.0.13 OS: NixOS Terminal: kitty, kitty+tmux

ToxicFrog commented 5 days ago

The root cause is tcell#28.

This tmux issue includes a workaround that is meant to cause tmux to unconditionally send the first field, but I haven't gotten it working. This only applies to how tmux parses OSC52 incoming from its containing terminal; what it sends to the programs inside it is hardcoded.