エラーコード:E513を克服する

去年の8月16日(日本では17日)にここで「E513エラー」が出るよー、と泣いていたわけですが、その後いろいろ調べて止めることに成功していたのですが、その件を書かずに放っておいたら検索している方が(かなりの数)いるようなので、ここでまとめておきます。

  • 症状

vim使用時に、起動後、

:set enc=utf-8

などとして、バッファに対する漢字コードを設定しようとする、あるいは、

:set fenc=euc-jisx0213

などとして、ファイルに対する漢字コードを設定しようとすると、

 E513: write error, conversion failed (make 'fenc' empty to override) 

というエラーが表示される。

  • 原因

起動直後のvimに漢字コードが設定されていないため、設定されていない値(エンコード値)から他の値(エンコード値)へのコンバートに失敗し、エラー表示となる。

バッファが持っている漢字コードは初期時に明示的に保持されている必要がある。

これはつまり、

vimを普通に(漢字コードの変換を考えずに)使用する場合は、たとえばWindows日本語環境で使用する際は、CP932として文字を表示し、そのままテキストファイルとして保存するので、無問題(オプションの“encoding”はWindowsから取得できる情報を元に自動的に設定される)なのだが、漢字コードを変換する場合はiconvを使用するため、どうしても、「どのコードページ(≒漢字コード)で起動した」かという情報が必要になる。

ということ(かどうかは、正直アヤシイ)。

  • 対処

これまでiconvを使って漢字コードを変換していたが(ていうか、vim7のいまもiconvを使っているわけですが)、その際、以下のような設定を%HOME%の.vimrcに書くことを推奨されていたと思う。

" 日本語を扱うために必要
set encoding=japan

" ファイルの漢字コード自動判別のために必要。(要iconv)
if has('iconv')
  set fileencodings&
  set fileencodings+=ucs-2le,ucs-2
  let s:enc_euc = 'euc-jp'
  let s:enc_jis = 'iso-2022-jp'
  iconvがJISX0213に対応しているかをチェック
  if iconv("\x87\x64\x87\x6a", 'cp932', 'euc-jisx0213') ==# "\xad\xc5\xad\xcb"
    let s:enc_euc = 'euc-jisx0213,euc-jp'
    let s:enc_jis = 'iso-2022-jp-3'
  endif
  fileencodingsを構築
  let &fileencodings = &fileencodings.','.s:enc_jis.',utf-8'
  if &encoding =~# '^euc-\%(jp\|jisx0213\)$'
    set fileencodings+=cp932
    let &encoding = s:enc_euc
  else
    let &fileencodings = &fileencodings.','.s:enc_euc
  endif
  定数を処分
  unlet s:enc_euc
  unlet s:enc_jis
endif

しかし、(おれの把握している限りでは)vim7以降のアーカイブにデフォルト(というか見本)として同梱されている.vimrcファイルには、「日本語対応のための設定:」として

source $VIMRUNTIME/encode_japan.vim

という一行があり、この「encode_japan.vim」ファイルを見ると、先の「ファイルの漢字コード自動判別のために必要。(要iconv)」と同じ内容になっていることがわかる。

そこで、先の「" 日本語を扱うために必要」から「endif」までの全25行(空行含まず)をコメントアウト(もしくは削除)する。

これで、vimは正しく漢字コード設定値の取得先を認識することができ、以後「:set enc=iso-2022-jp」しても「:set fenc=utf-8」してもE513を表示しなくなる(ハズ。少なくともおれのvimは想定どおりの動作をするようになった)。