I am writing a game engine for Bash using the cursor movement feature described here. However, if I echo emojis or other UTF-8 characters that span more than 1 byte, the cursor position seems to get messed up.
For example, the following code is supposed to echo "13", move the cursor back 3 positions and then echo "abc" in the same place. The result should only be "abc" (ideally). Instead, I see "1abc"
~ $ echo -e "13\033[3Dabc"
1abc
A similar problem can be illustrated with the carriage feed:
~ $ echo -e "13\rabc"
abc3
Is there any good way of resolving this? I am using the Terminal app on macOS. Is there any portable way of doing this?
Note: note, not all UTF-8 chars seem to behave this way. Mostly, I have only been able to reproduce this issue with emojis:
~ $ while true; do read -p "Enter emoji: " x; echo $x | hexdump; echo -e "1${x}3\033[3Dabc"; done
Enter emoji:
0000000 f0 9f 94 88 0a
0000005
1abc
Enter emoji: ♞
0000000 e2 99 9e 0a
0000004
abc
Enter emoji: ☞
0000000 e2 98 9e 0a
0000004
abc
Enter emoji:
0000000 f0 9f 98 8b 0a
0000005
1abc
Enter emoji:
0000000 f0 9f 83 98 0a
0000005
abc
Enter emoji:
0000000 f0 9f 80 96 0a
0000005
abc
Enter emoji:
0000000 f0 9d 95 ad 0a
0000005
abc
Enter emoji:
0000000 f0 9f 87 ba f0 9f 87 b8 0a
0000009
1abc
Enter emoji: ✎
0000000 e2 9c 8e 0a
0000004
abc