Tuesday, April 18, 2006

Mac 環境構築 その6 - vim の文字コード設定 [mac]

Mac でも快適に vim7 が使えるようになり,vim7 からは unicode サポートが改善されているとのことなので,これを機に vim のデフォルト文字コードを UTF-8 にしてみた.

vim の文字コード設定は少し複雑で,たまに間違って解説しているページも見かけるので,以下にまとめてみよう.

まず文字コード設定に関係するオプションは,
'encoding' (短縮名 'enc')
'fileencoding' (短縮名 'fenc')
'fileencodings' (短縮名 'fencs')
の3つ.fenc と fencs は名前が紛らわしすぎるので注意.

vim は 'enc' で指定された文字コードをデフォルトとし,ファイルを開く時に 'fencs' で指定された文字コードから順番に 'enc' の文字コードへ変換を試み,成功したところでやめる,全部失敗したら変換せずに 'enc' の文字コードで開く,という仕様になっている.だから,基本的に 'fencs' の中に 'enc' と同じ文字コードを書くのは無意味なばかりか,'fencs' の途中で 'enc' と同じものが登場すると以降の変換試行が行われない.

'fenc' は,vim がファイルを読み込む時に自動設定し,そのファイルの文字コードを示す為に使う.つまりユーザーが 'fenc' を設定するのは明示的にエンコーディングを指定して保存したい時のみで,.vimrc で 'fenc' を指定することは無い.たまに fenc を設定している解説ページを見かけるが,自分で設定するのは基本的に enc と fencs だけだ.もちろん明示的に fenc を設定する場合でも,指定できる文字コードは1つのみでカンマ区切りの書式は使えない.

文章だけだと分かりにくいですね.例えば
enc=utf-8
fencs=ucs-bom,iso-2022-jp,cp932,euc-jp
とあった時に,cp932 (SJIS) のファイルを開こうとすると,vim は
ucs-bom → utf-8 の変換
iso-2022-jp → utf-8 の変換
cp932 → utf-8 の変換
と試していき,ここで成功するので 'fenc' に cp932 を設定してファイルを開く.

'enc' と同じ UTF-8 のファイルを開いた時は ucs-bom から euc-jp まで全て試して失敗するので,そのまま UTF-8 で開き,'fenc' の値は空になる.

以上を踏まえた,UTF-8 をデフォルトとした .vimrc の文字コード設定例.

set   encoding=utf-8

if has('win32') && has('kaoriya')
  set   ambiwidth=auto
else
  set   ambiwidth=double
endif

if has('iconv')
  let s:enc_euc = 'euc-jp'
  let s:enc_jis = 'iso-2022-jp'

  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

  set   fileencodings&
  let &fileencodings = &fileencodings.','.s:enc_jis.',cp932,'.s:enc_euc

  unlet s:enc_euc
  unlet s:enc_jis
endif

if has('win32unix')
  set   termencoding=cp932
elseif !has('macunix')
  set   termencoding=euc-jp
endif
vim のデフォルトを UTF-8 にしても,ターミナルは cygwin が cp932,UN*X が euc-jp のままなので,それぞれ適切に termencoding を設定している (Mac のターミナルは UTF-8 にしている).


ちなみに以前の設定は以下のようなかんじ.'set enc=japan' としているが,これは enc で使えるエイリアスで,UN*X なら euc-jp,Windows であれば cp932 と解釈される.
set   encoding=japan

if has('iconv')
  let s:enc_euc = 'euc-jp'
  let s:enc_jis = 'iso-2022-jp'

  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

  set   fileencodings&
  set   fileencodings+=ucs-2le,ucs-2

  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 は未だあまりいじり倒していないのだが,鳥獣保護区さんのサイトに vim6 からの新機能がまとめられていたので紹介しておこう.
Vim 7.0 BETA リリース
Vim 7.0 の新機能

えーと,あれ? Mac の話とはあまり関係なかったな…


5 comments:

luna said...

初めまして。今年の夏頃にMacBookを購入した大学生です。
ようやく最近になってUnixであるMacとしてのスタートをきったところです汗
これからもちょくちょくこさせていただきます。
それでは失礼

toshi said...

luna さん,はじめまして.
Mac は UN*X マシンとしても素晴らしいですよね.

そういえば最近 Mac の話題書いてないな…

また気軽にコメントして下さいね.

omoon said...

とても参考になりました。ありがとうございます。

toshi said...

omoon さん,
どういたしまして :)
今後ともよろしくお願いします.

つっちぃ(TSUCHIDA Takuya) said...

enc,fenc,fencs をよくわからずに使用していたので,とても参考になりました.