Skip to content

Ambiguous width character の直後に文字が残ることがある #1126

@ichizok

Description

@ichizok

https://teratail.com/questions/103195

以前から気になっていたので、調べました。

再現手順

ファイル 1.txt , 2.txt を作成する。

$ vim --clean
:e 1.txt
:normal! izzzzzz
:w
:e 2.txt
:exe "normal!" "iab\u03bbef"
:w
  • \u03BB は λ

ambiguous width character を幅 1 で表示する端末上で、set ambiwidth=double を設定し 1.txt , 2.txt を順に開く。

$ vim --clean +'set ambw=double'
:e 1.txt
:e 2.txt

ambiwidth

λ の後ろに z が残る。<C-L> 等で消える。

原因

trachet で Vim の出力を見てみると、2.txt で λ を表示する部分は以下のようになっている。

>>>   CSI 1;1H                CUP / move cursor to (row=1, col=1)
>>>  abλ
>>>   CSI 1;5H                CUP / move cursor to (row=1, col=5)
>>>  ef
  1. カーソルを1文字目に移動
  2. abλ を出力
  3. カーソルを5文字目に移動
  4. ef を出力

Vim は λ を幅 2 で扱うため、 λ の直後のセルは飛ばして描画するが、端末側は λ を幅 1 で表示するので λ 直後のセルは更新されずに残ってしまう。

123456 (cell)
------
zzzzzz (1.txt 描画)
ab%    (2.txt: abλ 描画)
    ef (2.txt: ef 描画)
------
ab%zef (結果)

(幅を揃えるため、λ を % で代用した)

修正案

ambiwidth=double のときは、

  • ambiguous width character の後ろにスペースをつけて出力する
  • ambiguous width character の次の文字は常に再描画する(スペースを上書きするため)
>>>   CSI 1;1H                CUP / move cursor to (row=1, col=1)
>>>  abλ<SP>
>>>   CSI 1;5H                CUP / move cursor to (row=1, col=5)
>>>  ef

https://github.com/vim/vim/compare/master...ichizok:fix/redraw-ambiguous-width.diff

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions