Unicodeとの異体字バトルがはじまったぜ
あああああ、『邊󠄆』を nyagos のコマンドラインで扱うと、文字幅の解釈がおかしくなってしまう!まだだ、まだ 4.4.9_2 では終われない。俺たちの Unicode との戦いはこれからだ!Never End!
サポートしていない異体字セレクタコードだった。リストにコードを追加した。でも、いま異体字を表示できるターミナルはないので <U+xxxxxx>表記するしかない。あと、Ctrl-Yのペーストでは大丈夫だが、右クリックペーストでは異体字セレクタコード消えてしまう(受け取れない)
これは緊急性はないが
Windows Terminal では、異体字よく見ると、ちゃんとフォント変わってるわ!「U+908A 」単品と「U+908A U+E0104」では「しんにょう」の点の数が違うわ。これはサポートしたいな
WindowsTerminal で
fmt.Printf("[%c][%c%c]\n",0x908A,0x908A,0xE0104)
を実行すると
となる。これを コマンドプロンプトで行うと
になる。
いけると思ったが、よく見るとカーソル位置が違う。WindowsTerminal では3セル分文字幅を使っているように見えるが、実は4セル分カーソルが移動してしまっているという現象が発生する。これのせいで、
- ReadLineで{0x908A,0xE0104} を3セルとみなすと、見かけは3セルにしか見えないが、実際のカーソル位置は4セル分動いているから、カーソル位置の整合性が狂う
- ReadLineで{0x908A,0xE0104} を4セルとみなすと、カーソル位置は狂わないが、そのかわり再表示する時に文字が化ける
という現象が発生する。
本件と関係ありそうな issue で、Open にはなってるけど、半年以上放置されてる。ここで使われている検証プログラムでは俺の手元で判明している問題は表現できないはず。
どうおかしくなるかを確認できるコードを Go で書いた。
package main
import (
"fmt"
)
func main() {
fmt.Printf("[%c][%c%c]\n", 0x908A, 0x908A, 0xE0104)
fmt.Printf("[%c][%c%c", 0x908A, 0x908A, 0xE0104)
fmt.Printf("]\n")
}
1回で行われていた出力APIのコールを2回に分けると、カーソル位置のズレが表面化する。
ただし、Go言語は Windows の API コールを内部でそれなりにラッピングしているので、WindowsTerminal 開発陣に不具合だとアピールするには、切り分け根拠としてはちょっと弱い。C++ とかで書き直せればよいのだが
他の issue だと node.js による検証が許されているようだ。
scoop install nodejs
でインストール後、Windows Terminal を起動しなおしてから、node のコマンドラインで再試してみた。
> process.stdout.write("[\u908A\u{E0104}]\n")
[邊󠄄]
true
> process.stdout.write("[\u908A\u{E0104}") ; process.stdout.write("]\n")
[邊󠄄 ]
> process.stdout.write("[ABCD") ; process.stdout.write("]\n")
[ABCD]
true
true
Windows Terminal のレポジトリに issue 立てた。すでに 1000も Open issue があるようなプロジェクトなので、速やかにいくはずがないが…。再現コードを node.js / golang 双方で書いたし、スクショもはったし、伝わることを祈る
(外国の巨大OSSプロジェクトに issue たてるのは初めてである。外国人相手でも個人プロジェクトなら、なんぼか経験あるんだが…)
開発メンバーの人から I think this is covered in #3546. The Unicode support is not complete yet. という回答が来た。
まぁ、#3546 の存在は知ってはいたけれども、半年以上動きがないし、どうしたもんかなと思ってたんだよね。とりあえず、見た目玉アイコンで見たリアクションだけ入れておいた。まだトリアージされていないので、静観するしかないかな。やることはやった!
自分としては「そんな問題はない」とリジェクトされなかったのであれば、御の字である。問題さえ理解しておいて貰えれば、別にクローズされてもよいし。
なお、go-readline-ny に付属している unicodetest というテストツールで、0x908A+0xE0104 を内部的に4桁扱いにして、C-y ×数回 + C-a + C-f ×数回を実行すると、こんな感じに盛大に化ける。文字の途中にカーソルが移動してしまうせいかな
なお、このデモは nyagos 上で
go get github.com/zetamatta/go-readline-ny
cd ~/go/src/github.com/zetamatta/go-readline-ny
go build
cd unicodetest
echo %U+908A%%U+E0104% | clip
./unicodetest
で出来ます。ただし、現在はすでに回避コードが入っているので、文字化けまでは再現できなくなっています。
0x908A+0xE0104 などの Variation Sequence を出力する際
fmt.Fprintf(w, " \x1B7\b\b\b\b%s\x1B8", string(s))
と出力することで、力技で回避したwww
( ESC 7 はカーソル位置記憶、ESC 8 が記憶したカーソル位置に復帰するエスケープシーケンス)
WindowsTerminal での異体字の文字幅の不具合については回避策が取れるようになったので、次の nyagos 4.4.9_3 で異体字の編集ができるようになります
(ソースはコミット済み)
On WindowsTerminal, output IVS(U+E0100 to U+E01EF) as is. · zetamatta/go-readline-ny@5af1253
本当は WindowsTerminal 側に立てた issue
の推移を見届ける必要があるんですが、こっちはこっちで一応回避策が取れるようになったので、一旦、本スクラップはクローズしようと思います。
Unicodeとの異体字バトルが終わったぜ
ない、異体字セレクターの U+E0100 ~ U+E01EF ですが、Ctrl-Y ではペーストできるんですが、GUI操作のペースト(マウス右クリックからのペースト等)では通らないようです。これはどうしようもないです。
は重複ということで、クローズされたので、以後は
をウォッチ。まぁ、当面、動きないでしょうけども
WindowsTerminal 1.5 でも、まだ直ってない、ヨシ!?