0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VSCodeで等幅フォントを使っても、一部記号などのマルチバイト文字を使うとインデント文字数がずれる理由

Last updated at Posted at 2025-04-24

問題

VSCodeでは等幅フォントを使っても、一部のマルチバイト文字を使うとインデント文字数がずれる。
たとえばインデント文字数4で、以下のようになる。

image.png

  • 半角「A」や全角「A]の後に「タブ」「B」を入力した場合、 4文字目までインデント されて次の5文字目に「B」が表示される。
  • 全角「α」の後に「タブ」「B」を入力した場合、 5文字目までインデント されて次の6文字目に「B」が表示される。(インデント文字数がずれる)

※ちなみに、ずれているのは「インデント文字数」であり、フォントが原因の位置ずれは発生していない。
全角「A」「スペース2文字」「B」と打った場合と、全角「α」「スペース2文字」「B」と打った場合で、「B」が表示される横位置は完全に一致する。

原因

ギリシャ文字や数学記号は内部的には1文字幅として扱われているのが原因

VSCode(VSCodeのエディタ部分として採用される高機能なブラウザベースのコードエディタのMonaco Editor)は、「A」や「漢字」、「全角カタカナ」は2文字幅と認識されるのに対し、「α」や「■」などのギリシャ文字や記号は1文字幅と認識している。
つまり「α」は見た目は全角に見えても内部的には半角(1文字幅)扱いされてるため、タブ位置計算がずれてしまう。

なぜギリシャ文字や数学記号は1文字幅と認識されるのか

そもそも「文字幅」というものは、シングルバイト文字は1文字幅、マルチバイト文字は2文字幅と単純に決まるものではない。
Unicodeでは各キャラクタに East Asian Width (EAW) という「文字幅のヒント」プロパティが定義されており、VSCodeはこの定義で文字幅を判定している。

「α」等はこのプロパティが「Ambiguous; 曖昧」と定義されており、東アジア環境では2文字幅、欧米環境では1文字幅に見えることがある文字とされている。
つまり「α」は日本語環境では全角に見えるが、OSやフォント次第で半角に見える可能性がある。
そしてVSCodeでは欧米環境を優先するために、この Ambiguous な文字を常に「1文字幅」扱いにしている。

対策は無い ※対策をご存知の方が居ればご教示ください

これは日本語で VSCode を動かすときのために、Ambiguousを2文字扱いにするような機能があれば解決する筈ではある。
しかしどうもAmbiguousを1文字扱いするのはエディタコア機能で、簡単には変更できないらしく「α」を2文字扱いする設定や拡張機能は存在しない。

一応、Ambiguousを2文字扱いするパッチはあるようだ。
https://github.com/laurent22/joplin/commit/45c73f79629a91108a1366c6e50771e67110d85a
https://github.com/laurent22/joplin/issues/2674

結論としてはVSCodeではエディタのコア機能で「α」や「■」などは1文字扱いされているため、それを2文字扱いでインデントを入れることは出来ない。
……ということになる。
(Ambiguousを2文字扱いするようコード変更してビルドしたVSCodeを使えば別だが)


うーむ、ここ数年の検索しても解けなかった疑問だったがChatGPTがこの記事の7割くらいの内容を答えてくれた。
この子、賢すぎる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?