-
There are systems that do not implement Unicode equivalence, which may cause interoperability issues that are hard to fix.
- They are hard since two different but canonically equivalent sequences of characters are indistinguishable on the screen.
-
XFS, the default file system in RHEL 7, is one of such systems.
-
The following code will throw
NoSuchFileException
on XFS, but completes successfully on macOS/Windows:import java.nio.file.{Paths, Files} object FileNameGa extends App { val name1 = "が.txt" // precomposed character ('\u304c') val name2 = "が.txt" // decomposed character ('\u304b', '\u3099') that looks identical // create a file with name1, and read the file with name2 Files.write(Paths.get(name1), Array[Byte](0)) Files.readAllBytes(Paths.get(name2)) // the file is found only if the system implements Unicode equivalence }
-
-
The problem can be largely avoided by not mixing precomposed / decomposed characters.
-
Unicode defines, and Java supports the normalization forms that can solve the problem, but every one of them brings new obstacles.
-
NFD (decomposed) is not easy to work with; the vast majority of programming/authoring tools produces precomposed characters.
- One popular source of NFD strings is the file name in macOS Finder. If a file name is copy-pasted to Vim, there most likely is a problem since the macOS input method produces precomposed characters.
-
NFC (precomposed) not only composes characters, but also consolidates similar characters into CJK Unified Ideographs, while the vast majority of people casually distinguish those similar characters that carry subtly different sentiments.
-
The plugin warns/compose decomposed Unicode characters.
-
Build and publish to
~/.ivy2/local
mill plugin.publishLocal
-
Publish to Maven Central
mill plugin.publish --sonatypeCreds "user:pass" --release true
- macOS: install
gnupg
withbrew
- mill-0.3.6:
mill plugin.publish
fails withos.SubprocessException: CommandResult 2
ifgpg
tries to ask for the passphrase- To avoid the failure, make
gpg-agent
provide the passphrase, e.g.,LANG=en_US.UTF8 gpg -ab README.md
- To avoid the failure, make
- macOS: install