tmuxを使っているとよく困るのが「コピーモードでコピーした内容が、tmux内でしかペーストできない」問題。デフォルトのままだと prefix + [ でコピーモードに入り、範囲選択してコピーしても、その内容はtmux独自のバッファに入るだけで、macOSのクリップボード(pbcopy/pbpaste)とは連携しない。結果、他のアプリに貼り付けたいときに困る。
.tmux.conf に入れているコピペ関連の設定をメモしておく。
全体設定
# Option
setw -g mode-keys vi
## Bindings
set -g mouse on
set -g set-clipboard on
# copy mode
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key y copy-mode
bind-key p paste-buffer
各設定の解説
setw -g mode-keys vi
コピーモード内のキー操作をvi風にする設定。h/j/k/l でカーソル移動、v で範囲選択開始、y でヤンクといった、vimに慣れた人には馴染み深い操作感になる。デフォルトはemacs風のmode-keys emacsだが、vi操作に慣れているとこちらの方が使いやすい。
set -g mouse on
マウス操作を有効にする設定。マウスでペインを選択したり、ドラッグでコピーモードに入って範囲選択したりできるようになる。地味だが、マウスドラッグで直感的に選択できるのは便利。
set -g set-clipboard on
tmuxがシステムクリップボードとやり取りするためのオプション。tmuxが対応している端末(iTerm2やTerminal.appなど)であれば、OSC 52エスケープシーケンスを使ってクリップボードとの連携を試みる。ただし、これだけでは環境によって動作が不安定なことがあるため、下記のcopy-pipe-and-cancelと組み合わせるのが確実。
copy-mode-viでの明示的なpbcopy連携
ここが今回の設定の肝。
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
copy-mode-viテーブルに対して、Enterキー・yキー・マウスドラッグ終了(MouseDragEnd1Pane)のそれぞれに、選択範囲をパイプでpbcopyに流すcopy-pipe-and-cancelコマンドを割り当てている。copy-pipe-and-cancelは選択内容を指定コマンドの標準入力に渡し、コピーモードを抜ける処理(copy-pipeだとコピーモードに留まったままになる)。- これにより、キーボードで
yやEnterを押しても、マウスでドラッグして選択を終えても、確実にmacOSのクリップボードにコピーされる。set-clipboardだけに頼らずpbcopyを明示的に呼ぶことで、SSH越しの接続やクリップボード連携が弱い端末でも安定して動く。
bind-key y copy-mode / bind-key p paste-buffer
prefix + yでコピーモードに入る独自バインド(デフォルトはprefix + [)。y(yank)で覚えやすくしている。prefix + pはtmux内部バッファからのペースト。tmux内で完結するペーストが必要な場合はこちらを使う(macOS側のペーストは通常のCmd+vでOK)。
まとめ
tmuxでmacOSと違和感なくコピペするには、以下の3点がポイント。
set -g mouse onとsetw -g mode-keys viで操作感を整えるset -g set-clipboard onでtmux自体のクリップボード連携を有効化するcopy-mode-viの主要な確定操作(Enter/y/マウスドラッグ終了)すべてにcopy-pipe-and-cancel "pbcopy"を割り当て、確実にクリップボードへ送る
この3つを組み合わせることで、tmux内でコピーした内容をそのまま他のアプリにペーストできるようになり、ストレスがかなり減る。