その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

令和最新! Linux Desktop環境上の tmux (3.3a) でOSのクリップボードとtmuxのコピペバッファを直結する

Linux Desktop上でterminalを使っている時にOSのクリップボードとtmuxのコピペバッファを直結させたいという話です。
つまり Prefix + [ 等でtmux上で範囲選択してEnterを叩いた時にその内容がOSのクリップボードに格納され、Prefix + ]でペーストする時はOSのクリップボードから引っぱってきて貼り付ける、という挙動にしたいのです。なんでそういう挙動にしたいかというと、そういう設定で長らくmacOS上で生活してきたので……

TL;DR

Wayland環境の場合、xselxclipを使った方法は上手く動きません。wl-clipboardで提供されるwl-copywl-pasteを使わないと駄目でした。

example:

set -s copy-command 'wl-copy'
bind ] run "tmux set-buffer \"$(wl-paste)\"; tmux paste-buffer"

とりあえずこれで動いているという状況。

以下メモ。

tmux 3.2以降では copy-command が使える

tmuxのGitHub RepositoryのWikiにはClipboardという名前のそのものズバリな聖典があり、基本的にはこれを読むとほとんど解決します。なのでこれを読みましょうという感じなのですが、

tmux 3.2 introduced an option called copy-command to set a command to pipe to for all key bindings. This is used when copy-pipe is called with no arguments which is now the default. If the option is empty, the copied text is not piped.

To pipe to xsel(1):

set -s copy-command 'xsel -i'

The more complex configuration in the next section also works with tmux 3.2 and later versions.

https://github.com/tmux/tmux/wiki/Clipboard#how-to-configure---tmux-32-and-later

とあるように、tmux 3.2以降ではcopy-commandという設定項目が導入されているのでこれを使うと手っとり早いです。あらゆるモードでのtmux上でのコピー時に、これで指定したコマンドがフックされて実行されます。つまり、OSのクリップボードにコピーした内容を叩き込むコマンドをここに指定すると良いということです。上記の例では xsel が使われていますが、Wayland環境だと上手く動かなかったのでwl-copyに変えてあげる必要があるでしょう。
古いバージョンのtmuxの場合はドキュメントに書かれているようにもうちょい複雑な設定を細々書かなきゃ駄目で面倒なので、copy-commandがあって良かったですね。

ただこれはあくまでコピーの設定なのでペーストは別途設定する必要があり、ペーストについては聖典にもあんま有効な情報は書かれていません。
なので素朴に

bind ] run "tmux set-buffer \"$(wl-paste)\"; tmux paste-buffer"

とすることで Prefix + ] 時に wl-paste を実行してOS側のクリップボードから内容を引っぱってきて、それをtmuxのpaste bufferにつっこむことで実現しているという感じです。X11環境であればxsel/xclipも使えるのではないでしょうか。

set-clipboard を使えば良いのでは?

set -g set-clipboard on のようにしてset-clipboardを有効にしてやると、

that on both makes tmux set the clipboard for the outside terminal, and allows applications inside tmux to set tmux's clipboard (adding a paste buffer).
https://github.com/tmux/tmux/wiki/Clipboard#changing-set-clipboard

とドキュメントにも書いてあるようにtmux外のクリップボードと連携し、paste bufferについても連携するようであります。
一見するとこれで良いじゃん! となるのですが、set-clipboardのHow it worksのセクションに書かれているようにOSC 52に対応しているターミナルエミュレータを使う必要があります。まあ使えば良いんですが、使っているターミナルがOSC 52に対応していなかったので今回は諦めることに。
というか、試しにOSC 52対応のKittyをインストールして set-clipboard をonにして使ってみたのですが、tmux上でのコピーはOSのクリップボードへ行く一方で、OSのクリップボードからtmuxのpaste bufferに入れられないという挙動になってしまっており、まあなんか厳しいなと思って撤退しました。このへんそこまで深く検証してないです。

まとめ
  • 結局、tmux上のコピーイベントとペーストイベントにフックして、OSのクリップボードと適切にやりとりするソフトウェアを呼び出してインターフェイスする方法が安定する
    • Waylandだとwl-clipboardが提供するツールを使う必要がある。X11だったらxselとかxclipとかは依然使えそう。
  • OSC 52対応端末だと set-clipboardをonにするともしかしたら一発で動くかもしれない (軽く試した感じ駄目だった)。