WSLでクリップボードを共有する

Windows Subsystem for Linuxで開発環境を整えた の続きの記事です。まともに使ってみたところ、NeovimのyankがWindowsのクリップボードに入ってくれないのが結構ストレスになったのでそれの解消をします。

Windowsにはclip.exeというソフトウェアが搭載されており、これを使うことでWSLからWindowsのクリップボードに文字列を入れることができます

echo ":innocent:" | clip.exe

# wsl Terminal上でShift + Insert
:innocent:

ただ、このソフトウェア単体だとクリップボードから文字列を取り出すことができないのと、文字列の最後に改行コードが入るらしく(余計なことしやがって)つらいので別のアプローチでやります

先にやっておくこと

  1. https://github.com/equalsraf/win32yank/releases から win32yank-x64.zipをダウンロードしてきて展開
  2. 展開して出てきたwin32yank.exeを WSL上でecho $PATHして列挙されたディレクトリのいずれかに配置

win32yankの使い方は clip.exe と大体同じで以下のように使う

echo "poepoe" | win32yank.exe -i

win32yank.exe -o
poepoe

念のためWindows上で任意のテキストボックスでCtrl+vして貼り付けられるか確認しておくと良いかもしれない。

Neovimからwin32yank.exeを使う

さてここまでできたのなら、Neovimから yでヤンク、pで貼り付けるみたいなことをできるようにしたい。

過去の記憶からNeovimでLinuxのクリップボードと連携した時に xsel に依存していた覚えがあった。

また、丁度手元にNeovimのソースコードがあったのでそこから検索して(最悪書き換えてビルドすればよい)どうすればいいかを模索した

cd ~/src/github.com/neovim/neovim
git grep xsel
runtime/autoload/provider/clipboard.vim:" When caching is enabled, store the jobid of the xclip/xsel process keeping
runtime/autoload/provider/clipboard.vim:  elseif exists('$DISPLAY') && executable('xsel') && s:cmd_ok('xsel -o -b')
runtime/autoload/provider/clipboard.vim:    let s:copy['+'] = 'xsel --nodetach -i -b'
runtime/autoload/provider/clipboard.vim:    let s:paste['+'] = 'xsel -o -b'
runtime/autoload/provider/clipboard.vim:    let s:copy['*'] = 'xsel --nodetach -i -p'
runtime/autoload/provider/clipboard.vim:    let s:paste['*'] = 'xsel -o -p'
runtime/autoload/provider/clipboard.vim:    return 'xsel'
runtime/doc/provider.txt:  - xsel (if $DISPLAY is set)

なんか普通に設定方法がドキュメントに書いてありそうなので、調べてみたところg:clipboardを弄ることにより変更できるみたいだった。

以下のように変更した

let g:clipboard = {
      \   'name': 'myClipboard',
      \   'copy': {
      \      '+': 'win32yank.exe -i',
      \      '*': 'win32yank.exe -i',
      \    },
      \   'paste': {
      \      '+': 'win32yank.exe -o',
      \      '*': 'win32yank.exe -o',
      \   },
      \   'cache_enabled': 1,
      \ }

さてこのままだと、マルチプラットフォーム対応として怪しいのでもうちょっと工夫をする。

WSLの uname -a は特殊になっており、普通のUbuntuとは表示が違うことを利用して判定をする

uname -a
Linux HOSTNAME 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86\_64 x86\_64 x86\_64 GNU/Linux
if system('uname -a | grep Microsoft') != ""
  let g:clipboard = {
        \   'name': 'myClipboard',
        \   'copy': {
        \      '+': 'win32yank.exe -i',
        \      '*': 'win32yank.exe -i',
        \    },
        \   'paste': {
        \      '+': 'win32yank.exe -o',
        \      '*': 'win32yank.exe -o',
        \   },
        \   'cache_enabled': 1,
        \ }
endif

tmuxからwin32yankを使う

vi-mode使ってること前提。

if-shell 'test "$(uname -a | grep Microsoft)" != ""'  bind-key -t vi-copy Enter copy-pipe "cat | win32yank.exe -i"

まとめ

WSLでもクリップボード共有できて嬉しいですね。多分これで常用できると思います

拍手ボタン