I've now solved the display issue by making my Perl script change the codepage to 65001 just like CMD's `dir` does:
use feature ":5.16"; # Include say and Unicode string functions.
use open ':std', ':encoding(UTF-8)'; # Print Unicode without complaining about wide chars.
use utf8; # Unicode source code.
use strict; # Don't ignore undefined variables.
use Win32::Console;
Win32::Console::OutputCP(65001); # Tell Windows Terminal to render Unicode (with unclustered graphemes in 1.23.13503.0 but they copy/paste ok).
my $file_name = "emoji_🎅🎉😀💢👩🏾🚀.txt";
say "Writing to ${file_name}";
open( my $fh, ">", $file_name ) or die "Can't write $file_name: $!";
binmode($fh, ":encoding(UTF-8)"); # encoding() also checks UTF-8 validity, unlike ":utf8".
say $fh "My name is \"$file_name\".";
close($fh);
say "Reading ${file_name}";
open( $fh, "<", $file_name ) or die "Can't read $file_name: $!";
binmode($fh, ":encoding(UTF-8)");
read($fh, my $buf, 100);
say $buf;
close($fh);
say "Done.";
This won't affect the codepage of the terminal after, just like `dir`:

And despite the female black astronaut not rendering as a single character, it copy/pastes just fine:
15:23:45 C:\apps\StrawberryPerl\perl\bin>chcp
Active code page: 850
15:23:50 C:\apps\StrawberryPerl\perl\bin>perl C:\Users\C\Documents\code\Perl\test_unicode.pm
Writing to emoji_🎅🎉😀💢👩🏾🚀.txt
Reading emoji_🎅🎉😀💢👩🏾🚀.txt
My name is "emoji_🎅🎉😀💢👩🏾🚀.txt".
Done.
15:23:53 C:\apps\StrawberryPerl\perl\bin>chcp
Active code page: 850
Unfortunately, writing the emoji file name only appears to work correctly inside a shell inside VS Code; not inside a shell inside Windows Terminal 1.23.13503.0:

Newer languages like Python do work.
file_name = "emoji_🎅🎉😀💢👩🏾🚀.py.txt"
print(f"Writing to {file_name}")
with open(file_name, "w", encoding="utf8") as f:
f.write(f"My name is \"{file_name}\".")
print(f"Reading {file_name}")
with open(file_name, "r", encoding="utf8") as f:
print(f.read())
print("Done.")
No comments:
Post a Comment