見えない敵「ゼロ幅スペース」可視化してる?——各エディタの設定まとめ

コードレビュー中、「Bitbucket上ではおかしくないコードだったのに、手元のNeovimで開いたら<200b>が大量に挟まっている」ということが何度かありました。
<200b>つまりはゼロ幅スペースU+200Bです。

今回はNeovimで可視化されていたから気づけたものの、 「これ環境によっては永遠に気づけないままでは?」 と思ったので調べてみました。

## そもそもゼロ幅スペース(U+200B)とは

ゼロ幅スペースは「表示はされないスペース」です。改行位置とかを指定するときに使われたりします。UnicodeではU+200Bです。

エディタでは設定されてないと見えないので、想定外の問題が起こりそうで怖いですよね。

### どんなときに混入するか

普通に書いてたら混じりませんが、他のツールなどからコピペすると入ってくることがあります。
筆者はMiroからのコピペで遭遇しました。

## エディタで可視化する

エディタによっては自分で設定しないと見えないやつがあります。気になったのでメジャーなエディタの設定方法を調べてみました。

### Vim / Neovim

Vim・Neovimだとデフォルトでゼロ幅スペースが見えます。このおかげで気づけました。感謝。

Vimのデフォルトでゼロ幅スペースを可視化

の間にガッツリ<200b>が見えていますね。

### Emacs

Emacsはデフォルトだと可視化されないようです。

Emacsのデフォルトだとゼロ幅スペースは可視化されない

でも数行設定すれば可視化できました。今回はで置き換えています。

(setq whitespace-style '(face spaces tabs newline space-mark))
(setq whitespace-display-mappings
'((space-mark ?\u200B [?␣])))
(global-whitespace-mode 1)

※筆者はEmacs全然触らないので、もっといい方法とかあるかも?

設定を足してemacsでもゼロ幅スペースを可視化

### VSCode・VSCode派生系

VSCodeとその派生系のエディタは厄介です。

まず、デフォルトだと可視化されません。
次のように設定しても可視化されない箇所があります。

{
"editor.unicodeHighlight.invisibleCharacters": true,
"editor.unicodeHighlight.includeComments": true,
"editor.unicodeHighlight.includeStrings": true
}

画像の例ではHTMLのabc:の後の部分だけ検知しており、の間のやつは検知できてません。

VSCodeの設定だけだとゼロ幅スペースは可視化されるところとされない箇所がある

たぶんこのissue?:Cannot highlight U+200B and unhighlight multiple languages at the same time · Issue #176273

### 拡張機能で可視化

というわけで拡張機能を入れましょう。

#### 純正VSCodeの場合

まず純粋にVSCodeなら拡張機能Gremlins trackerを普通にインストールすればOKです。

入れるとこんな感じです。

Gremlins trackerによってゼロ幅スペースが可視化された

#### VSCodeの派生エディタの場合

派生エディタの場合、拡張機能のマーケットプレイスが違うので注意です。Open VSXというやつです。
Gremlins trackerはOpen VSXに登録されていません(Feature requestのissueは出てました)。

Open VSXで使えそうな拡張機能は無かったので、Gremlins trackerをローカルでパッケージ化して入れる他無いようです。

ざっくりとですが、手順を書きました。

Terminal window
git clone git@github.com:nhoizey/vscode-gremlins.git
# package.json編集して、 engines.vscodeを"^1.99.0" に書き換える
npm install
npx @vscode/vsce package

vsceでパッケージ化したら、拡張機能のメニューのInstall from VSIX...から作成されたVSIXファイルを指定すればインストールできます。

VSIXから拡張機能をインストール

### Zed

Rust製のエディタの方のZedも見てみました。デフォルト対応です。

Zedだとデフォルトでゼロ幅スペースが可視化

## コマンドで一覧を出す

ここまではエディタの設定でした。どうせならLinterで検出できた方が便利なんですが、たとえば「メールテンプレートのpug」とかだと対応Linterは無さそうです。

というわけで、コマンドで検索しましょう。

Terminal window
grep -r $'\xe2\x80\x8b' .

なんかもっといい方法あったら追記します。

## エディタ以外

ざっと試した所、catやbatコマンド、lazygitのプレビューなどでも可視化されません。

## 検証に使ったリポジトリ

ゼロ幅スペースを入れたMarkdown・HTMLファイルの検証用リポジトリを用意しました。

eetann/compare-editors

GitHub上では可視化されないので、cloneして前述のようにエディタを設定してから確かめてください。


以上、ゼロ幅スペースの可視化設定についてでした。

余談ですが最近Nixを始めたので、未インストールだったEmacsとZedをさくっと試せて神でした。

Terminal window
# こんな感じのコマンド
nix run nixpkgs#emacs -- -q -l ./init.el invisible-unicode.md
nix run nixpkgs#zed-editor