LoginSignup
15
15

More than 5 years have passed since last update.

Vimからクリップボードインテグレーションシーケンス(PASTE64/OSC52)を利用する

Last updated at Posted at 2013-01-01

はじめに

今回もまたxterm由来のクリップボードインテグレーション(PASTE64/OSC52)の話題なんですが、先日iTerm2がサポートしたことで、ほんのちょっとだけ認知度が上がったようですね。よかったです。
PASTE64/OSC52って何のことか知らないという人は、お先にこちらをどうぞ。

Vimからの利用

この機能はXが無い環境からでもssh先とクリップボード連携できるという特性があり、なかなか使い勝手がよいものです。
tmuxだけにつかわせておくのはちょっともったいないですよね。

そこで今回は、VimにPASTE64/OSC52をインテグレートする設定例を書いてみました。


function! s:Paste64Copy() range
  let l:tmp = @@
  silent normal gvy
  let l:selected = @@
  let l:i = 0
  let l:len = strlen(l:selected)
  let l:escaped = ''
  while l:i < l:len
    let l:c = strpart(l:selected, l:i, 1)
    let l:escaped .= printf("\\u%04x", char2nr(l:c))
    let l:i = l:i + 1
  endwhile
  if $TMUX != ""
    "tmuxのとき
    call system('printf "\x1bPtmux;\x1b\x1b]52;;%s\x1b\x1b\\\\\x1b\\" `echo -en "' . l:escaped . '" | base64` > /dev/tty')
  elseif $TERM == "screen"
    "GNU Screenのとき
    call system('printf "\x1bP\x1b]52;;%s\x07\x1b\\" `echo -en "' . l:escaped . '" | base64` > /dev/tty')
  else
    call system('printf "\x1b]52;;%s\x1b\\" `echo -en "' . l:escaped . '" | base64` > /dev/tty')
  endif
  redraw!
endfunction

command! -range Paste64Copy :call s:Paste64Copy()

.vimrcにこれを書いて、テキストを選択後、

:'<,'>Paste64Copy

とコマンドを打ち込んでやれば、OSC52シーケンス経由でのクリップボードコピーができます。
もちろんSSH越しでも使えます。

解説

Vimから端末に対して、任意のタイミングで生文字列を送る方法をちょっと探してみたのですが、どうやらsystem関数でやるしかなさそうだったので、ここではそうしています。
正直こんなかっこわるいやり方はゆるせない、と思っているので、他にもっといい方法があれば教えてください。

さて、OSC52シーケンスが制御端末まで届いたとしても、まだ障害があります。
GNU Screenやtmuxのようなターミナルマルチプレクサは、基本的に自分の知らないシーケンスを全部たべてしまうので、フロントエンド端末まで届かないのです。
私がターミナルマルチプレクサを使わない理由の3割くらいはこれなんですが、普通の人は使うと思うので、ここではGNU Screen/tmuxの独自拡張であるパススルーシーケンスを使用し、OSC 52を貫通させました。
GNU Screenとtmuxでのエスケープの仕方の違いを考慮するあたりがとても重要なポイントですね。

15
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15