大学生からの Web 開発

会社の人に見つかってぽよぽよしてきた

Vim で JSON のダブルクォーテーションが表示されない場合の解決法

ずっとこの問題が解決しなくて、VimJSON 開きたくなさすぎてしばらく Atom 使ってたんだけど解決したのでたまに戻ります。

Qiita にも同じエントリーを投下した。

Vim で JSON のダブルクォーテーションが表示されない場合の解決法 - Qiita

おことわり

このへんを参考にしてかつ下の設定をしても解決しない場合に、このエントリを参照してください。

set conceallevel = 0
let g:vim_json_syntax_conceal = 0

Yggdroot/indentLine 導入してない?

この問題を引き起こしてるのは、Vim の conceal という機能だ。conceal は、「視認性が良くないコードの見た目を変えて見やすくしようよ」という機能。

Yggdroot/indentLine はインデントラインの表示のために conceallevel = 2を後から設定していて、それだと MacVim 標準の JSON Syntax でダブルクォーテーションが非表示にされてしまう。別に indentLine に限らず、そういうことをしているプラグインは多くあると思う。

適当な JSON ファイルを vim で開いて、:set conceallevel=0 にすればクォーテーションが表示されるのを確認してほしい。

解決法

自分は MacVim の記事作成時での最新版(snapshot 74)の kaoriya パッチ版を使っているんだけど、それだと JSON Syntax が同じ作者が作られている Syntax より少し古いもので、ダブルクォーテーションを隠すことを無効化する設定が記述されていない。

以下では、JSON Syntax 内で無効化できるようにして、無効化させる設定を書くアプローチで解決する。

Synatax ファイルの比較

見てほしい点は、if has('conceal') のところ。最新版だと g:vim_json_syntax_conceal == 1 もあってブロック内が実行されるんだけど、MacVim 標準だと conceal が有効になっていれば実行される。conceal は特別な方法で Vim をインストールしていない限りは有効になっていると思う。

最新版 2014/12/20 更新

vim-json/json.vim at 3dccc18eded2e782870d7134b0045b297caee758 · elzr/vim-json

" Vim syntax file
" Language:   JSON
" Maintainer: Eli Parra <eli@elzr.com> https://github.com/elzr/vim-json
" Last Change:    2014-12-20 Load ftplugin/json.vim
...
...
" Syntax: JSON Keywords
" Separated into a match and region because a region by itself is always greedy
syn match  jsonKeywordMatch /"\([^"]\|\\\"\)\+"[[:blank:]\r\n]*\:/ contains=jsonKeyword
if has('conceal') && g:vim_json_syntax_conceal == 1
   syn region  jsonKeyword matchgroup=jsonQuote start=/"/  end=/"\ze[[:blank:]\r\n]*\:/ concealends contains=jsonEscape contained
else
   syn region  jsonKeyword matchgroup=jsonQuote start=/"/  end=/"\ze[[:blank:]\r\n]*\:/ contains=jsonEscape contained
endif
...

MacVim 標準 2014/8/23 更新

macvim/json.vim at 503a01b2eeaad6bb3b66f2192dc6615fe703da2e · splhack/macvim

" Vim syntax file
" Language:   JSON
" Maintainer: Eli Parra <eli@elzr.com>
" Last Change:    2014 Aug 23
" Version:      0.12
...
...
" Syntax: JSON Keywords
" Separated into a match and region because a region by itself is always greedy
syn match  jsonKeywordMatch /"\([^"]\|\\\"\)\+"[[:blank:]\r\n]*\:/ contains=jsonKeyword
if has('conceal')
   syn region  jsonKeyword matchgroup=jsonQuote start=/"/  end=/"\ze[[:blank:]\r\n]*\:/ concealends contained
else
   syn region  jsonKeyword matchgroup=jsonQuote start=/"/  end=/"\ze[[:blank:]\r\n]*\:/ contained
endif
...

この 2 つ、互換性があって上のをコピペすればいいっていうわけじゃなくて、vim-json はレポジトリ内の他のファイルに依存しているのでコピペするとエラーを吐く。

vim-json 入れよう

早い話が elzr/vim-json を導入して、シンタックスが上書きして無効化できるようにする。

NeoBundle 'elzr/vim-json'
let g:vim_json_syntax_conceal = 0

NeoBundle を導入していない人は各自の方法で。

まとめ

ダブルクォーテーション表示されていないのに記述する分にはちゃんと書かないといけないの、気持ち悪すぎたので本当によかった。