I use Kakoune in WSL and usually inside tmux, which made setting up hooks for copying to system clipboard and/or tmux buffers, and keeping track of both a bit cumbersome.
I recently learned about and set up copying to system clipboard using OSC 52 escape sequence, after seeing that tmux has a set-clipboard
option. They also recently created a very nice wiki page explaining its usage and OSC 52.
I found a few advantages to using the escape sequence:
- tmux integration is transparent with the
set-clipboard on
option: If tmux is running, the escape sequence sent by an application will set tmux buffer which will get forwarded to the terminal by tmux, otherwise it will have directly sent it to the terminal
- The clipboard will get forwarded through SSH sessions, so that you can copy from terminal applications from the remote application
Kakoune setup
Following the examples in Kakoune wiki, we can hook up the escape sequence to a yank/delete/change operation:
hook global NormalKey y|d|c %{
nop %sh{
encoded=$(printf %s "$kak_main_reg_dquote" | base64 | tr -d '\n')
printf "\e]52;;%s\e\\" "$encoded" >/dev/tty
}
}
tmux setup
AFAICT tmux 2.6+ supports the set-clipboard on
option, while the default is set-clipboard external
which will let applications set the tmux buffer but tmux will not forward them to the terminal. set-clipboard on
will also enable forwarding to the terminal to set the system clipboard.
Terminal support
Most terminals seem to have support for setting the system clipboard when the sequence is received. The aforementioned tmux wiki page details support for most terminals, some of which requires setting options; a notable holdout is VTE terminals like Gnome terminal.
I use WSLtty which is not documented there, but it supports it by setting AllowSetSelection=true
in its config file.
4 Likes
alacritty
- not documented on the tmux wiki page - works, too, with this trick.
I’m quite happy with this setup!
1 Like
For whatever reason the hook, or this equivalent script doesn’t work on Ubuntu 16 (it just prints the sequence to stdout), while it works fine on Ubuntu 20.
#!/bin/sh
stdin=$(cat /dev/stdin; echo .)
stdin=${stdin%.}
encoded=$(printf %s "$stdin" | base64 | tr -d '\n')
printf "\e]52;c;%s\a" "$encoded" >/dev/tty
Maybe I need to copy a terminfo entry or something?
The weird thing is if I run that printf
command in a shell, it works fine.
ok seems to be a problem with the version of dash on Ubuntu 16; it works when I use bash instead
I think I still didn’t manage to configure tmux to interpret OSC 52 but it turns out I can skip that for most scenarios because I can just write to the underlying TTY that tmux runs on top of. Here’s what I use, it works great over SSH
printf "\e]52;c;%s\a" "$encoded" > "$(tmux display-message -p '#{client_tty}')"
That’s a good trick to know, there might be scenarios where you want to bypass tmux anyway. I have been using this approach with set-clipboard on
for some time now, most recently with Windows Terminal.
It’s possible to join selections using the following pattern:
nop %sh{
printf 'echo -to-file "%s" -- "%%val{selections}"' "$kak_response_fifo" > "$kak_command_fifo"
tr '\0' '\n' < "$kak_response_fifo"
}
1 Like
I recently ran into some trouble using this approach with clients connected to headless servers, where /dev/tty
is no longer accessible from the server. mawww pointed to /proc/$kak_client_pid/fd/0
on Discord as a way to find the tty of the client (at least on Linux) so the copy command can be updated to the following to be more robust:
printf "\e]52;;%s\e\\" "$encoded" >"/proc/$kak_client_pid/fd/0"
1 Like
I ran into an issue after migrating to Void Linux from Fedora where the command as given rendered the escape sequence with base64-encoded code on the screen and did not successfully update the system clipboard. The updated line that worked for me removed the \e
’s:
printf "\033]52;;%s\a" "$encoded" >"/proc/$kak_client_pid/fd/0"
2 Likes