debian stretch時代のtmux事情(East Asian Width問題)

debian stretch時代のtmux事情(East Asian Width問題)

TL;DR

  • tmux 2.2以降になった。(stretch以降)
  • custom charmapを置くことでαや─├などが全角扱いされるよ!(昔から)
  • tmuxで表示が崩れなくったヤッター(stretch以降)

East Asian Widthとは

Unicodeにおける全角と半角に相当する概念を取り扱ったものです。UAX #11: East Asian Width が詳しいです。この中にAmbiguous(以後A文字と記す)という文脈によって文字幅が異なる文字が規定されています。実際どの文字がA文字に該当するかはhttp://ftp.unicode.org/Public/UNIDATA/EastAsianWidth.txt を参照してください。

この中でA文字としてαなどのギリシャ文字や─などの罫線素片が含まれています。

とくにこの罫線素片がA文字に含まれていることがターミナルユーザーには大きな問題が起こっていました。

libcと文字幅判定

POSIXの中にはwcwidthあるいはwcswidthと言うワイド文字(列)を表示幅をはんていするAPIが存在します。ncursesなどのCUIを提供するライブラリが各文字の幅を参照する場合もこのAPIから情報を取得していたりします。Debianにて標準的に使われているglibc実装ではwcwidthが参照する情報は/usr/share/i18n/charmap以下にあるファイルに記述されていて、UTF-8の場合は全てUTF-8.gzを参照しています。

はい、欧米・東アジアロケール関係なくUTF-8のlocaleはコレを参照してます

このファイルの生成は上記のEastAsianWidth.txtからスクリプトで生成されているらしいです。

d.hatena.ne.jp

このA文字の扱いを全角扱いにするcharmapを公開されている方が居られました。感謝

github.com

 

 

tmuxの場合(tmux 2.2未満まで)

上記のcharmapで解決するのはwcwidthに基づいて文字幅を判定している物のみです。

2.2未満のtmuxがこの例外に当てはまり、かつてのtmuxではutf8フラグ存在していました(2.5現在は無い筈)。このフラグをONにするとペイン間の分割がUnicode罫線素片を使用するようになったり、tmux内部にハードコーディングされた判定処理を用いて文字幅を判定したりするようになっておりました。

eagletmt.hateblo.jp

この判定処理にはA文字の取り扱いを行う特別な対応などは存在せず、すべて半角扱いされていました。tmux 2.2では文字幅の判定はwcwidthなどの外部ライブラリを参照するようなりました。

 

debian stretchのtmux事情

リリースされたdebian stretchではtmux 2.3が採用されており上記の問題は解決しました!Yatta!