SEANK.H.LIAO

osc 52

clipboard over ssh for nvim

OSC 52

ever yanked something in nvim, switched to another window to paste, then remembered the nvim was through ssh and it didn't share a clipboard with your system?

First discovered while reading through the chrome ssh / hterm faq, OSC 52 uses escape sequences to let you send things through to the local clipboard. Requires a terminal emulator support.

testing for support

run the following in an ssh session

copypasta! should appear in your local clipboard ready for pasting

printf "\033]52;c;Y29weXBhc3RhIQ==\a\n"

vim plugins

neovim

The vim plugins didn't work when i tested them, looking at the neovim issues, 8450 stood out. That script basically worked, but requires an extra script outside. Available gist

or slightly simplified

in init.nvim with set clipboard=unnamedplus

1let g:clipboard = {
2     \ 'name': 'myClipboard',
3     \     'copy': {
4     \         '+': 'clipboard-provider copy',
5     \     },
6     \     'paste': {
7     \         '+': 'clipboard-provider paste',
8     \     },
9     \ }

in $PATH

 1#!/bin/bash
 2#
 3# clipboard provider for neovim
 4#
 5# :help provider-clipboard
 6
 7#exec 2>> ~/clipboard-provider.out
 8#set -x
 9
10: ${COPY_PROVIDERS:=tmux osc52}
11: ${PASTE_PROVIDERS:=tmux}
12: ${TTY:=`(tty || tty </proc/$PPID/fd/0) 2>/dev/null | grep /dev/`}
13
14main() {
15    declare p status=99
16
17    case $1 in
18        copy)
19            slurp
20            for p in $COPY_PROVIDERS; do
21                $p-provider copy && status=0
22            done ;;
23
24        paste)
25            for p in $PASTE_PROVIDERS; do
26                $p-provider paste && status=0 && break
27            done ;;
28    esac
29
30    exit $status
31}
32
33# N.B. buffer is global for simplicity
34slurp() { buffer=$(base64); }
35spit() { base64 --decode <<<"$buffer"; }
36
37tmux-provider() {
38    [[ -n $TMUX ]] || return
39    case $1 in
40        copy) spit | tmux load-buffer - ;;
41        paste) tmux save-buffer - ;;
42    esac
43}
44
45osc52-provider() {
46    case $1 in
47        copy) [[ -n "$TTY" ]] && printf $'\e]52;c;%s\a' "$buffer" > "$TTY" ;;
48        paste) return 1 ;;
49    esac
50}
51
52main "$@"