🙅‍♂️

【tmux】ヤンク(コピー)後にコピーモードが終了してしまう

に公開

はじめに

tmux を使用してターミナルに出力された文字列をコピーする場合、コピーモードを使ってヤンク操作をすればクリップボードにヤンクした文字列が保存される。
しかし自分の環境ではヤンクするとコピーモードが自動終了し、画面がプロンプトまで自動的にスクロールする挙動となっていた。
コマンド履歴が古いものを連続でヤンクしたい場合に、毎回その位置までスクロールしないといけないのがストレスだったので原因を調査することにした。

環境

  • Win11 WSL2 Ubuntu 24.0.4
  • Alacritty
  • tmux

先に結論

tmux.conf でヤンクのキーバインドを copy-pipe-and-cancel から copy-pipe に変更する。

tmux.conf
bind -T copy-mode-vi y send -X copy-pipe "iconv -t utf16le | clip.exe"

WSLの環境で日本語をコピペすると文字化け

もともと Windows でコピーした日本語文字列が WSL 環境へペースト時に文字化けする対策として、参考記事を元に tmux.conf に以下のキーバインドを設定していた。

tmux.conf
bind -T copy-mode-vi y send -X copy-pipe-and-cancel "iconv -t utf16 | clip.exe"

上記はコピーモード時にヤンク(y キー押下)で選択文字列をパイプで iconv に渡し UTF-16 変換、その後 clip.exe に渡してクリップボードに保存している。
日本語文字列を UTF-8 で扱っている場合に貼り付けを行うと文字化けするようで、文字コードの変換を事前に行っている。
詳しくは以下の記事を参照。

参考記事

WSLの環境からWindowsにclip.exeするときの文字化け対処 #WSL2 - Qiita
tmux - WSL2にしたらコピペできなくなった - Logicky Blog

copy-pipe-and-cancelcopy-pipe の違い

しかし、上記のキーバインドで指定した copy-pipe-and-cancel はヤンクしたあとにコピーモードを終了する動作になる。

ヤンクしてもコピーモードを継続したい場合は copy-pipe-and-cancelcopy-pipe に変更する。

tmux.conf
bind -T copy-mode-vi y send -X copy-pipe "iconv -t utf16 | clip.exe"

このあたりの動作については man コマンドに詳細が書かれていた。

man tmux
copy-pipe [command] [prefix]
        Copy the selection, clear it and pipe its text to command.  prefix is used to name the new paste buffer.

copy-pipe-and-cancel [command] [prefix]
        Same as copy-pipe but also exit copy mode.

ヤンクした文字列を貼り付けたら先頭に“<feff>”という文字列が挿入される

copy-pipe に変更したのが原因ではないと思われるが、キーバインド変更後に動作確認していたらヤンクした文字列の先頭に“<feff>”という文字列が挿入されるようになった。

この文字列についてはこちらの記事から推測すると UTF-16 の BOM かと思われる。
特定アプリケーションでは文字列として表示されてしまう場合があるみたい。

この問題については BOM なしの UTF-16LE を使うことで解消できた。
最終的に tmux.conf のヤンクキーバインドは以下のようになった。

tmux.conf
bind -T copy-mode-vi y send -X copy-pipe "iconv -t utf16le | clip.exe"

おわりに

見る習慣がなさすぎて man コマンドの存在をすっかり忘れていたが、マニュアルはしっかり読もう。

Discussion