mosh can't display emoji
Describe the issue
Mosh under msys2 can't display characters that need more than 2 bytes to encode in utf-16.
Steps to Reproduce the Problem
- Connect to any host using mosh
- Run
printf '\U000102A1\n' - It prints
��instead of🩹
Additional Context: Operating System, Screenshots

Everything seems to work properly if I use ssh instead of mosh, or mosh under wsl. Locale is set to en_US.UTF-8 on both sides.
OS: Windows 10 Pro version 21H2 19044.1706
+1. i face the same issue.
In my setup, printf '\U000102A1\n' does not print the emoji character but printf '\xf0\x9f\xa9\xb9\n' does. The same thing happens with and without mosh. See the attached screenshot.
- \xf0... is U+1FA79 not U+102A1
- MSYS2: printf '\U0001fa79' 🩹
- What is mosh?
- As one of the printf commands above outputs two glyphs rather than one, is the shell a Windows program? What does
type moshsay?
https://github.com/mobile-shell/mosh/issues/234#issuecomment-1549068087 I do some research. I found the Cell contents is string type, may be this is problem.
If mosh is a Windows program (see my question 4 above), output is likely to be incompatible with UTF-8 handling.
Make a screen log (mintty -l log), produce the issue, and upload the log here.
well i took ten hours try to find what's wrong. Then I find that the following code does not work right in msys2.
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#include <stdio.h>
#include <string>
int main() {
setlocale(LC_ALL, "zh_CN.UTF-8");
wprintf(L"wcwidth of 0x269C is %d\n", wcwidth(0x269C));
std::wstring in = L"📁💕😘😒🤦";
wprintf(L"length of string in is %d\n", in.size());
for (std::wstring::const_iterator i = in.begin(); i != in.end(); i++)
{
wprintf(L"wcwidth = %d\n", wcwidth(*i));
}
wprintf(L"%ls", in.c_str());
return 0;
}
Result in msys2
wcwidth of 0x269C is 1
length of string in is 10
wcwidth = -1
wcwidth = -1
wcwidth = -1
wcwidth = -1
wcwidth = -1
wcwidth = -1
wcwidth = -1
wcwidth = -1
wcwidth = -1
wcwidth = -1
📁💕😘😒🤦
Result in debian or WSL
wcwidth of 0x269C is 1
length of string in is 5
wcwidth = 2
wcwidth = 2
wcwidth = 2
wcwidth = 2
wcwidth = 2
📁💕😘😒🤦
but there is no libc in msys2.
$ ldd a.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7fff75af0000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7fff743a0000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7fff72f10000)
ADVAPI32.DLL => /c/WINDOWS/System32/ADVAPI32.DLL (0x7fff75980000)
msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7fff75350000)
sechost.dll => /c/WINDOWS/System32/sechost.dll (0x7fff74470000)
RPCRT4.dll => /c/WINDOWS/System32/RPCRT4.dll (0x7fff74f60000)
msys-stdc++-6.dll => /usr/bin/msys-stdc++-6.dll (0x526840000)
msys-gcc_s-seh-1.dll => /usr/bin/msys-gcc_s-seh-1.dll (0x5e8160000)
msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
I suggest that using another way to split string into cells would be bring a high compatibility.
So the emojis are displayed in your test program. If you wonder about the lenghts, that's related to UTF-16 encoding but it's another issue.
mosh is a msys2 package which is like ssh. mosh use wcwidth to deal with strings. as the length is not good, mosh can not process emojis correctly.
Running ssh from MSYS: printf '\U0001fa79' 🩹 I think you should report this to mosh.
yes. but if wcwitdh works good(someone say it was related to the version of libc), maybe mosh could be fine too.