Fix Garbled Copied Text with Tmux-Yank in WSL 2
By default tmux-yank uses clip.exe to copy text and it currently doesn't support all UTF-8 characters like emojis.
For a long time now I’ve noticed whenever I copied certain text from my
terminal in Windows with WSL 2, such as the output of tree
or emojis I
wouldn’t get what I expected when pasting. The characters would come out
garbled such as seeing ✨
instead of ✨.
When running native Linux or macOS (my dotfiles are cross OS compatible) I did not experience these issues so that led me to believe my baseline tmux config was probably ok.
Ultimately I isolated it down to copying text with tmux-yank. Every other scenario (no tmux, tmux but using its built-in copy mode, copying from Neovim, etc.) was fine.
Since I use tmux a lot I experienced this a lot, it was especially noticeable
when using tree
and wanting to paste its output somewhere.
For example if I copied this:
$ tree
├── pyproject.toml
├── README.md
└── run
3 files
After pasting it anywhere I would get this:
$ tree
├Γö£ΓöÇΓöÇ pyproject.toml
Γö£ΓöÇΓöÇ README.md
ΓööΓöÇΓöÇ run
3 files
Let’s go over the root cause and how I worked around it so you can too.
#
Tmux-Yank Is Coded to Use clip.exe
If It Exists
After isolating things to tmux-yank I looked at its code to see how it’s copying text.
Long story short it has a big if / else condition to use a number of well
supported clipboard tools like pbcopy
, clip.exe
, wl-copy
, xsel
, xclip
and more. The basic idea there is as soon as it finds a clipboard command that
exists it will use that.
That is a reasonable strategy. It avoids needing to do OS detection and instead focuses on which commands are available.
It checks for clip.exe
before xclip
so even if you have xclip
installed
in WSL 2 it never gets a chance to use it because clip.exe
was found first.
But why is that problem?
#
clip.exe
Doesn’t Fully Handle UTF-8 Encoded Text
I never looked into the gory details of clip.exe
’s code but a few sources on
the internet said characters outside of the basic ASCII character range aren’t
supported.
That explains why emojis and tree’s lines and connectors get messed up. You can
test this by running echo "├──" | clip.exe
in WSL. When pasting, it will come
out garbled.
It’s possible in the future Microsoft will fix this but who knows. For now
avoiding it seems like a good idea. I never depended on using clip.exe
in WSL
anyways. I always used native Linux tools like xclip
and then used VcXsrv and
now WSLg to handle clipboard sharing between WSL and Windows.
# Fixing the Issue
In my dotfiles I already have a clipcopy
wrapper script to copy text to your
clipboard in a cross OS compatible way. The tmux-yank plugin also has a way to
override which clipboard tool to use so I defined set -g @override_copy_command "clipcopy"
in my tmux
config.
If you’re not using my dotfiles that’s ok, you have a few options. You can do
the same and use your OS’ clipboard tool directly instead of clipcopy
.
Alternatively you can patch this function in
tmux-yank
to either comment out the elif to use clip.exe
or move that condition near
the bottom so xclip
or whatever you use gets selected first.
In any case you’ll want to restart tmux with tmux kill-server
and run tmux
again to apply your config changes. You can also restore tmux sessions using
tmux-resurrect, I have another post about that.
I ended up opening an issue for this on tmux-yank. I’d be open to making a PR depending on what the author prefers if they respond. Who knows, maybe by the time you read this the problem will be solved out of the box!
The video below walks through all of the above and shows the problem / solution.
# Demo Video
Timestamps
- 0:29 – Demonstrating the problem
- 1:19 – Debugging to identify the root cause
- 2:22 – Identifying the problem with clip.exe
- 3:23 – Solving this in a few different ways
- 4:30 – Demoing the fix
- 5:15 – Not using my dotfiles? You can patch tmux-yank
Did you also run into this issue? Let me know below.