East Asian Ambiguous Width Character

テキストエディタなどで → など一部の記号が入っている時に表示崩れなどが発生する問題。

問題

unicodeambiguous width に分類される文字があると、以下の問題を起こす。

  • 表示の乱れ
  • カーソルの表示と内部バッファの位置のズレ

つまりまともに編集できなくなる。
(大体においては行単位でバッファの管理をしているので、行単位でおかしくなる)

原因

ambiguous width は、文字コードとして文字幅の規定がされていないのでアプリ側で表示する際の文字幅を確認して扱わないといけない。
問題が出るのは以下の2パターン。

  • ambiguous width の文字幅を設定ファイルなどで指定すれば扱える(指定しないとダメ)
  • そもそも対応が考えられていない

対応

vim

vimの場合は幸いというかもちろんというか原因として前者なので、設定ファイルで ambiguous width の文字幅を指定する。
.vimrc

set ambiwidth=double
screen

East Asian Ambiguous 対応としてパッチで提供されているので再インストールが必要。
https://savannah.gnu.org/bugs/?16666#postcomment

# すでにインストールされている場合はアンインストール
yum remove screen

# screen ソースをダウンロード
wget http://ftp.gnu.org/pub/gnu/screen/screen-4.0.3.tar.gz
tar zxvf screen-4.0.3.tar.gz
cd screen-4.0.3

# パッチのダウンロード
wget screen-4.0.2-patch-cjkwidth-cvs-2006052001

# その他のパッチもついでにダウンロード
wget ftp://www.dekaino.net/pub/screen/screen-4.0.2-deadlock-patch
wget ftp://www.dekaino.net/pub/screen/screen-4.0.2-hankanacopy-patch

# パッチを当てる
patch < screen-4.0.2-deadlock-patch
patch < screen-4.0.2-hankanacopy-patch
patch < patch-cjkwidth-cvs-2006052001

# インストール
./configure
make && make install

screenの East Asian Ambiguous 対応パッチを読んでみる

utf8の文字単位に文字幅を確認する関数内で、East Asian Ambiguous かどうかを確認する為の文字コードテーブルが追加されてる。

int
utf8_isdouble(c)
int c;
{
// 〜 中略 〜
    /* sorted list of non-overlapping intervals of East Asian Ambiguous
    * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
    static const struct interval ambiguous[] = {
        { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
        { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
// 〜 中略 〜
        { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
        { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
    };