fish_clipboard_copy: use OSC 52 when running inside SSH
When connecting to a remote system via SSH, Control-X either does nothing, or if a clipboard-copying program is installed, tries to copy into the remote system's clipboard, which often fails.
Modern terminal emulators implement the OSC 52 escape sequence for setting the clipboard of the terminal host system. Use OSC 52 in fish_clipboard_copy when running inside SSH. Give it precedence over all other cases since that behavior is probably better than setting the clipboard of the remote system.
Tested on foot, iTerm2, kitty, tmux and xterm (which requires "XTerm.vt100.allowWindowOps: true").
Should also work in screen and Windows Terminal. On terminals that don't support OSC 52 (like Gnome Terminal or Konsole), it seems to do nothing (but with this patch we also don't delegate to pbcopy and friends, so I hope no one relies on that).
I think there is also an escape sequence to request pasting the system clipboard but that's less important and less popular, possibly due to security concerns.
Johannes and I spoke about this in person and it's an awesome feature but I have concerns about not calling the traditional fallbacks if the OSC escape isn't supported. I know we don't do terminal-identification as a general rule, but I think we need to do something because this could break a lot of configs.
FWIW: I had to look it up, but xterm's XTerm.vt100.allowWindowOps defaults to true.
@krobelus does "Windows Terminal" mean just that app or also cmd.exe?
Ok there are several cases:
-
ssh localhost- yes, this one will be broken if the terminal doesn't support OSC 52. We could work around this though I'm not sure how? Probably not a big deal since it's a nonsensical use case. -
ssh remote-host. Here it means we stop writing the clipboard of the remote system but who wants that anyway? 0. I guess this could matter for some remote desktop setups, but wouldn't the terminal then also run in remote desktop, so without SSH_PTY defined?- I failed to think about X11 forwarding, which means remote xclip uses the local X server. Luckily we can just detect if DISPLAY is defined and skip OSC 52 if yes.
- I haven't tested with remote macOS, but I can imagine that
pbcopy/pbpastework (but on the remote system)? Though that's a skewed expectation; using the local clipboard is more correct.
FWIW: I had to look it up, but xterm's
XTerm.vt100.allowWindowOpsdefaults to true.
On my system it doesn't :(
does "Windows Terminal" mean just that app or also cmd.exe?
I'm not sure but probably just the app since it's more modern?
I'm not the Windows expert in the room, is it possible to ssh into windows and want to use the clipboard there?
If there's a chance we break anyone, we can just do both: the old behavior, and additionally write the OSC 52 sequence.
ssh remote-host. Here it means we stop writing the clipboard of the remote system but who wants that anyway?
@krobelus I'm not sure if you remember as we spoke about this in person in passing, but it's not safe to assume fish_clipboard_copy and fish_clipboard_paste are strictly for the local machine.
In my minimal fish config, one of the few things I override is fish_clipboard_copy (indirectly, by defining my own pbcopy and pbpaste) to support remote copy-and-paste over SSH:
https://github.com/mqudsi/fish-config/blob/12b7ebb5bfb049807e583ce76dc8b4eb89553deb/functions/pbcopy.fish
# Implement remote copy-and-paste via `lemonade` (a go utility) - note that it doesn't support IPv6:
if type -q lemonade; and string length -q $SSH_CLIENT; and not string match -rq ':' $SSH_CLIENT
set -l host (echo $SSH_CLIENT | cut -f1 -d ' ')
lemonade --host $host copy 2>/dev/null
return
end
(Please don't judge the snippet too harshly - it was for my eyes only and I'm sure there are many issues with my string manipulation and testing!)
I'm fairly sure I'm not the only one doing something along these lines, even if not everyone has their fish config on GitHub for us to find.
I'm all for adding support for this escape, but given the patchy client support I think we would have to continue calling fish_clipboard_copy. There are issues if they behave differently, e.g. one could trim trailing empty lines as a function of the utility it goes through and the other might not, etc. and I'm not sure how we should resolve that race condition (if it's a race at all; after all, the order we execute them in is deterministic) but that would be better than not calling fish_clipboard_copy at all.
I'm also sorry to learn that XTerm.vt100.allowWindowOps doesn't default to true on your machine - what's your distribution? It seems that true is the (current?) [default value upstream](https://www.x.org/releases/X11R6.7.0/doc/xterm.1.html#:~:text=allowWindowOps%20(class%20AllowWindowOps,default%20is%20%60%60true.%27%27) but (though saddened) I'm not surprised to learn that it depends on the packager. If we don't even have basic xterm support out-of-the-box that's definitely all the more reason to not rely on the OSC escape on its own.
Oh, and yes, I use the same functionality when SSHing into my Windows box as well (although SSH into Windows has only recently become non-niche with somewhat tenuous upstream support).
In my minimal fish config, one of the few things I override is fish_clipboard_copy (indirectly, by defining my own pbcopy and pbpaste) to support remote copy-and-paste over SSH:
If you override fish_clipboard_copy, you can override fish_clipboard_copy some more?
As I see it: The current copy/paste over ssh is typically useless, and OSC 52 has at least a fighting chance of doing something useful instead.
Of course if you have a better way of doing it on your systems, this doesn't stop you from doing that. It's a function, it's super easy to customize!
Fair enough!
I don't think it's a big deal at all, but just fyi and from previous experience, this will cause local fish copy/paste to fail if used locally on a machine with a tmux session that was started remotely (and, vice versa, won't perform remote copy and paste if the tmux session was started locally but that's less of an issue). Again, super niche and not a blocker, but just for posterity.
what's your distribution?
Arch Linux, here is the xterm build configuration. Probably some configure flag is missing but I don't really care.
In my minimal fish config, one of the few things I override is fish_clipboard_copy (indirectly, by defining my own
pbcopyandpbpaste) to support remote copy-and-paste over SSH
Actually I did the same thing - I created a function pbcopy that writes the OSC 52 sequence.
It's very hacky but it's the solution with the fewest lines :)
Not sure if we should keep such configurations working. I guess it's basically free. No strong opinion here.
this will cause local fish copy/paste to fail if used locally on a machine with a tmux session that was started remotely
Good find. When using detachable terminals, environment variables are not flexible enough to tell the origin of a terminal. A future terminal protocol extension could do that. Though the easiest solution is for terminals to support OSC 52, then there's no problem.
This is more complicated than expected. I realized I still haven't managed to configure tmux correctly - it only worked when writing to /dev/tty - I used a similar workaround that also works if a tmux session was started somewhere else. I've also left pbcopy in for now and fixed some cases where su/sudo would break fish_clipboard_copy.