Vim:日本語の文字化けへの対応を攻略。もう怖くない!

最終更新:2023-06-16 by Joe

Vimの日本語文字化けへの対応方法をまとめました。vimで日本語ドキュメントを開くたびにどきどきしていた自分。文字化けするんじゃないか、解決できなくてまたまごつくんじゃないか・・。そんな臆病な自分と決別するための記事です。

Vimで日本語が文字化けした時の対応

日本語などのマルチバイト文字の文字化けは新しいサーバー環境ではよく起こります。慌てず騒がず、まずは、状況の確認から。

Vim で文字化けの直し方:

  1. 現在の「Vim 内部のエンコーディング形式」を確認する
  2. うまく表示されるエンコーディング形式を探す
  3. ファイルの今後のエンコーディング形式を決め、変更を保存する
  4. 今後のために、Vim の起動時の設定を行う。

それでは、1つずつ見ていきましょう。

1現在の「Vim 内部のエンコード形式」を確認する

まずは、現状の確認から。

Vimでファイルを内部的に特定のエンコーディングで文字データを認識し、画面に表示していますが、これは vim のマニュアルでは「Vim 内部のエンコード形式(encoding used inside Vim)」と呼ばれていますので、ここでもそのように呼んできます。

さて Vim はファイルを開く時に、自動的にファイルがどのエンコーディングを使って保存されたかを判別してくれています。日本語のようなマルチバイト文字はこの自動判別が失敗しやすく、文字化けとして表示されます。

Vim を開いてコマンドモードで下記を入力します:

# 現在の vim のエンコード形式を確認するコマンド
:set encoding?

# 省略形。同じ意味です
:set enc?

下記のいずれか(または別かもしれません)のような結果が表示されるはずです:

#出力結果の例
encoding=

encoding=sjis

encoding=euc-jp

encoding=latin1

新しいサーバー環境では、多くの場合 latin1 がかえってきます。例えば、「encoding=utf-8」と表示されたのであれば、Vimとしては「utf-8でエンコードして保存されたファイルだと見なしてデコードして、表示している」という事です。

このように「開いたファイルが最後に保存されたときのエンコード形式」と、Vimの内部エンコーディング(すなわち、set: encoding? の値)があわず、日本語部分などマルチバイトの文字は正しくデコードされず、文字化けとして画面に表示される、というのが文字化けの原因となります。

ボクのファイルでも、encoding? が latin1 って出力されみたい。

Vimマニュアルにも書いてあるが、それはだいたいエンコーディングがうまく自動判別できなかったときの出力なのじゃ・・。latin1 形式を積極的に使う場面など、普通はないからの。。

2うまく表示されるエンコーディング形式を探す

さて、解決を試みます。Vim では、現在の内部エンコード形式を下記のコマンドで変更できます。

# 現在の vim の内部エンコード形式を変更するコマンド
:set encoding=utf-8

# 省略形。同じ意味です
:set enc=utf-8

上記は :set enc=utf-8 への変更例ですが、utf-8 がうまくいかなければ、いくつかのエンコード形式を試してします。

エンコード形式で代表的なのは:

utf-8, sjis, iso-2022-jp, euc-jp, ucs2le, ucs-2, など

おそらくうまくいく文字コードが見つかるはずです。

※内部エンコード形式の変更時に、まれに、ファイル冒頭やファイル末尾の「バイトずれ」などによって、エラーが起きることがあります。この場合、ファイル冒頭・末尾に、適宜改行やスペースなどの8バイト文字の入力を加えて一度保存すると、解決できることがあります。

さて、その文字コードでファイルを開き直すには「:e」を実行します。また「++」に続けて、実行コマンドを付与できます。いつくか思いつく文字コードを、えいっえいっと試してみて下さい。「sjis」「euc-jp」「utf-8」などとやれば、だいたいうまくいくと思います。

# ファイルを開き直す(euc-jpで開き直す場合)
:e ++enc=euc-jp

# あれっ、うまく行かたなかった・・、sjisも試してみる
:e ++enc=sjis
何故かうまくいかないことも・・:MacOS の Excel の問題

筆者が先日、MacOS 上の Excelで出力したCSVファイルのエンコード形式の判別において、いろいろ複雑な事になっているようで、「エンコード形式は何か?」に対して、正しい答えがわかりません。筆者もこれはVim上で解決できませんでした。

現状わかっている解決手段は、いったんエクセルから

ツールバー > インポート > CSV

とすすみ、文字コードを「Japanese (Mac)」で一旦開けますので、別の文字コードで保存するために、そこからクリップボードを経由して、Google Spreadsheetなどから、再度CSVを吐き出す、などでしょうか・・・。

3ファイルの保存時の、エンコード形式を指定する

さて、たとえばSHIFT-JIS 形式で保存されたファイルを開いて、上記の方法で文字化けを改善して、そのまま、内容も変更したと、仮定します。

基本的には、ファイルのエンコーディングには、utf-8 の利用が推奨されますので(※開発チームや、その環境でのルールに従いましょう)今後のことも考えて「uft-8」に変換して保存しておきましょう。

Vim では、fileencoding が、ファイルを保存するときのエンコーディング形式を指定するコマンドです。

# 保存エンコーディングを明示的にセット(utf-8で保存する)
:set fileencoding=utf-8

# ファイルを保存する。
:w

# 注)念の為、ファイルを別名で、保存する場合。
:saveas text_utf-8.html

これで、文字化けしないファイルの完成です。解決できましたね?

追加対応:vim設定ファイルに対応を書き込む

さて、上位で行った事を頻繁に行わなかればいけないとき、毎回対応するのは大変なので、デフォルトの設定を、~/.vimrcに書いておきます。

上記では言及しなかったのですが、Vimの設定値に「fileencodings」(最後の「s」に注意)「fileformats」という値があります。「fileencodings」は、Vim起動時の文字コードの自動判別で、設定値の左から順番に試して「成功」と判別されたら、その文字コードで開きます。判別に成功したその時点で、自動的にそのfileencoding, fileformat値が、それぞれ、fileencodingやfileformatに(一時的に)設定されます。

ですので、.vimrcに対して、下記のように、よくある化け種類の正解コードを左側に書いておくと、先に判別され、そのコードで開いて貰える確率が上がると思います。

どう設定しておくべき?というのは、自分の状況や、チームの状況によるとおもいますので、必要に応じてカスタマイズして使って下さい。

##################################
# Vim起動時に、判別の優先度を定める設定
##################################

# ファイルを読み込む時の、文字コード自動判別の順番
:set fileencodings=utf-8,cp932,euc-jp,sjis


##################################
# Vim起動時に、強制する設定
##################################

# vimの内部文字コード (これを書くと、上記の優先度設定が無視されます)
:set encoding=utf-8

# ファイルのエンコーディング(改行コードの種類)
:set fileformat=unix

もちろん、vim 起動中も「:set fencs?」「:set ff?」などを実行すれば、現在の設定を確認できますからね。

参考リンク

日本語っていろいろ大変ですね。でも、上記を把握しておくと、結構文字コードが怖くないです。類似の話題で、改行コードに関してはこっちも参考にどうぞ。

Vimの保存に関して参考リンクです。

さすがにマニュアル詳しいですね、難しいけど。