yuntan_t blog

neovim

#neovim #dotfiles #tmux

TL;DR

let s:osc52_copy = {lines, regtype ->
\ chansend(v:stderr, printf("\x1b]52;;%s\x1b\\", system("base64", join(lines, "\n"))))}
let s:osc52_paste = {-> getreg('"', 1, 1)} " fallback
if !exists('$TMUX')
  let g:clipboard = {
\   'name': 'osc52',
\   'copy': {
\     '+': s:osc52_copy,
\     '*': s:osc52_copy,
\   },
\   'paste': {
\     '+': s:osc52_paste,
\     '*': s:osc52_paste,
\   },
\   'cache_enabled': 1,
\ }
endif
set -g set-clipboard on

OSC 52制御文字列とは

CLIアプリとクリップボードを連携するためのXTermの制御文字列. XTerm Control Sequences

OSC 52に対応している端末エミュレーターで以下のコードを試すと,クリップボードの内容を変更できる.

printf "\x1b]52;;%s\x1b\\" "$(base64 <<< "hello")" # "hello" をクリップボードに送信

以下のコードでクリップボードの内容を取得できる(…はずだが,なぜか上手くいかない)

printf "\x1b]52;;?\x1b\\"; awk -F ";" '{print $3}' | base64 -d

利点

  • OSに依存しない
    • xclippbcopyなどのプログラムを指定しなくてもOSのクリップボードを読み書きできる.
  • SSHで使える
    • X11転送ssh -Xの代わりに使える.

欠点

  • 対応している端末エミュレーターが少ない
    • 特に,OSC 52 ?にはセキュリティ上の理由で対応していないアプリがほとんど.
  • クリップボードの内容をvim/tmuxに反映することができない
    • neovimでクリップボードの内容の取得を試したが手段が見つからなかった.
    • tmuxはクリップボードの内容の取得に対応していない.

neovimの設定

neovimのclipboard-providerとして登録する.:h provider-clipboardを参照.

let s:osc52_copy = {lines, regtype ->
\ chansend(v:stderr, printf("\x1b]52;;%s\x1b\\", system("base64", join(lines, "\n"))))}
let s:osc52_paste = {-> getreg('"', 1, 1)} " fallback
if !exists('$TMUX')
  let g:clipboard = {
\   'name': 'osc52',
\   'copy': {
\     '+': s:osc52_copy,
\     '*': s:osc52_copy,
\   },
\   'paste': {
\     '+': s:osc52_paste,
\     '*': s:osc52_paste,
\   },
\   'cache_enabled': 1,
\ }
endif
  • clipboard providerから/dev/ttyにアクセスできないので,ワークアラウンドとしてchansend(v:stderr, "hello")を使う.
  • tmuxの上にnvimが乗ってるときは,providerを追加せずにデフォルトで用意されているtmux providerを使う.
  • OSC52?(クリップボードの内容の取得)を試したが,上手いやり方が見つからなかった.
    • 失敗例
    • code:vim
    • let s:osc52_paste = {–> system(“base64 -d”, split(chansend(v:stderr, “\x1b]52;;?\x1b\”), “;”)[2])}
    • code:vim
    • let s:osc52_paste = “echo -en '\x1b]52;;?\x1b\'; awk -F ';' '{print $3}' | base64 -d”
  • ひとまず"registerの内容を持ってきて誤魔化している.
    • code:vim
    • let s:osc52_paste = {–> getreg('“', 1, 1)} ” fallback

tmuxの設定

tmuxはOSC52?(クリップボードの内容の取得)には対応していない. – OSC 52 clipboard reading · Issue #1477 · tmux/tmux

set -g set-clipboard on

OSC52に対応している端末エミュレーター

端末エミュレーターの設定

  • Alacrittyは設定不要.
  • RLoginの設定例

参考