vim でたまに文字化け

少し前から vim で ファイルを utf-8 で保存し、そのファイルを開くと文字化けをするようになった。
必ずなるというわけではなくて、たまに起きるから始末が悪い。
文字化けはファイルを utf-8 なファイルを cp932 に変換して、開いている。
e++enc=utf-8 とすれば、utf-8 なファイルになって、文字化けが解消されるけど、
毎回毎回 コマンドで変換するのは鬱陶しい。


文字コードの認識の部分は ずん Wiki のを vimrc を書いている。
http://www.kawaz.jp/pukiwiki/?vim#cb691f26


で、ずん Wiki に以下のように記述されている。

vim文字コード判定の仕組みは以下の通りです。

  • fileencodings の設定を前から順に試してはじめにマッチしたものが採用される
  • encoding や fileencoding の設定値が途中に発見されるとそこで判定を止めてしまい後の設定は無視される
    • この動作により、UNIX環境(euc-jpの場合)では euc-jp が fileencodings の前の方に設定されていると、cp932 や utf-8 で書いたファイルが文字化けてしまうので気をつける必要がある。
  • encoding に設定される文字コードは fileencodings に見つからなかったときのデフォルト値に使われるので fileencodings に設定する必要は無い。
http://www.kawaz.jp/pukiwiki/?vim#cb691f26

vim文字コードは上記のように判定するらしい。fileencodings の判定が誤作動したと思われる。


文字コード設定の前と後に、fileencodings を見てみたら、ucs-bom と表示され、
設定後は iso-2022-jp-3,euc-jisx0213,cp932,ucs-bom,utf-8,default,latin1 と表示された。


utf-8 なファイルだけど、cp932 として認識されているのは、先に cp932 でかけていて、認識されているからじゃないかと推測。

if has('mac')
  set termencoding=utf-8
  set encoding=utf-8
  set fileencoding=utf-8
  set fileencodings=utf-8,cp932
endif

" 文字コードの自動認識
if &encoding !=# 'utf-8'
  set encoding=japan
  set fileencoding=japan
endif

--snip--
" fileencodingsを構築
  if &encoding ==# 'utf-8'
    let s:fileencodings_default = &fileencodings

    if has('mac')
      let &fileencodings = s:enc_jis .','. s:enc_euc
      let &fileencodings = &fileencodings .','. s:fileencodings_default
    else
      let &fileencodings = s:enc_jis .','. s:enc_euc .',cp932'
      let &fileencodings = &fileencodings .','. s:fileencodings_default
    endif

    unlet s:fileencodings_default
  else
    let &fileencodings = &fileencodings .','. s:enc_jis
    set fileencodings+=utf-8,ucs-2le,ucs-2
    if &encoding =~# '^\(euc-jp\|euc-jisx0213\|eucjp-ms\)$'
      set fileencodings+=cp932
      set fileencodings-=euc-jp
      set fileencodings-=euc-jisx0213
      set fileencodings-=eucjp-ms
      let &encoding = s:enc_euc
      let &fileencoding = s:enc_euc
    else
      let &fileencodings = &fileencodings .','. s:enc_euc
    endif
  endif

-- snip --

とりあえず、これで認識に失敗してたファイルを開いたら、ちゃんと認識してくれるようになった。
ついでに、sjis、jis、euc-jp、utf-8文字コードのファイルをそれぞれ CotEditor で作って、
vim で開いたら、ちゃんと判定されているようだ。