Copy from tmux/nvim to clipboard over SSH
Copying text to clipboard when working on a remote machine via SSH can be tricky. While you can usually highlight text with your mouse to copy it to the primary selection clipboard (and paste with middle-click), this approach has limitations.
Two common scenarios where this falls short for me are:
I configure my n(vim) to show whitespace characters for clarity:
vim.opt.listchars = {
tab = '🡒 ',
space = '·',
nbsp = '␣',
extends = '⟩',
precedes = '⟨'
}
and the results look something like:
While these visualization characters are helpful, I don’t want them copied to my clipboard. Vim handles this correctly when using yank commands, but mouse selection in the terminal emulator copies everything - including the whitespace characters.
Similarly, copying from tmux sessions can be frustrating. While tmux has basic mouse support, selecting text becomes challenging when you need scrolling and/or are using split panes:
Using OSC-52 for Remote Clipboard Access
OSC-52 is an escape code that instructs terminals to copy text into the system clipboard. While not an official standard, it’s widely supported by modern terminals like kitty.
The basic format is:
\033]52;c;BASE64_ENCODED_PAYLOAD\007
When a terminal receives this sequence with base64-encoded text, it copies the decoded content to the system clipboard.
Kitty ships a kitten clipboard
utility that handles clipboard integration using OSC-52. For simpler needs, I wrote this minimal bash script saved as clipwrite
that I use on remote machines:
#!/usr/bin/env bash
printf "\033]52;c;%s\007" "$(base64 -w0 < /dev/stdin)"
Usage is straightforward:
echo "foobar" | clipwrite
Configuring neovim to use OSC-52
You can configure neovim to use OSC 52 for both primary (*
) and clipboard (+
) registers:
vim.g.clipboard = {
name = 'OSC 52',
copy = {
['+'] = require('vim.ui.clipboard.osc52').copy '+',
['*'] = require('vim.ui.clipboard.osc52').copy '*',
},
paste = {
['+'] = require('vim.ui.clipboard.osc52').paste '+',
['*'] = require('vim.ui.clipboard.osc52').paste '*',
},
}
This allows you to use normal Neovim clipboard operations (like “+y to copy or “+p to paste) and have them work across SSH.
Configuring tmux to use OSC-52
Enable OSC 52 in your tmux.conf
:
set -g set-clipboard on
(See tmux documentation for more details.)
For quickly copying entire tmux buffers, which is often what I want to do, I use this shell alias:
alias tmux2clip='tmux capture-pane -pS - | clipwrite'