Vimで改行コードを変更して開き直す(fileformat)
Windowsで作られたファイルをLinuxサーバー上で編集していたら、行末に見慣れない^Mが表示されました。改行コードの違いが原因で、Vimには読み込み時に改行形式を指定し直す方法が用意されています。
目次(11項目)
| コマンド | これだけ覚える |
|---|---|
:e ++ff=unix | LF(Unix)形式で開き直す |
:e ++ff=dos | CRLF(Windows)形式で開き直す |
:set ff? | 現在の改行形式を確認 |
改行コードを指定して開き直す
:e ++fileformat=dos " Windows形式(CRLF)
:e ++fileformat=unix " Unix形式(LF)
:e ++fileformat=mac " 旧Mac形式(CR)
省略形の++ff=でも同じように指定できます。これは文字コードを指定して開き直す++enc=と同じ発想の仕組みで、読み込み時の解釈だけを変更します。
現在の改行形式を確認する
:set fileformat?
:set ff? " 省略形
ステータスラインに表示する設定をしておけば、開くたびに毎回確認しなくても現在の形式が一目で分かります。文字コードと改行コードを合わせて表示する設定は文字コードの確認方法で扱っています。
改行コードを直接入力する
| キー | 入力される改行コード |
|---|---|
| Ctrl-v Ctrl-m | CR(復帰) |
| Ctrl-v Ctrl-l | LF(改行) |
特殊な改行コードをテキスト中に直接埋め込みたい、という場面は限られますが、バイナリに近いテキストデータを扱うときに使うことがあります。
新規作成ファイルのデフォルト
既存ファイルを開く場合とは別に、新規ファイルを保存するときの改行コードはfileformats(複数形)の先頭の値が使われます。クロスプラットフォームで開発しているチームでは、この初期値をあらかじめunixに固定しておくと、意図せずCRLFで新規ファイルが作られる事故を防げます。
保存時の改行コードにも注意
ここまでは読み込み時の話ですが、保存時にどの改行コードで書き出すかはfileformatの値がそのまま使われます。++ff=で読み込み直した状態で保存すると、指定した形式で書き出されるので、Windows向けにCRLFへ統一したいときなどはこの仕組みが使えます。
:e ++ff={形式}で開き直せば解決できます。読み込みと保存の両方に影響するので、変換したい場合はこのコマンドで開き直してから保存します。
Windows環境で作成された設定ファイルをLinuxサーバーで編集するたびに^Mが表示されて煩わしく感じていました。:e ++ff=unixで開き直してから編集し、そのまま保存する流れを覚えてからは、改行コードの不一致に悩まされることがほぼ無くなりました。fileformatsの初期値をunixに固定してからは、そもそも意識する場面自体が減りました。
Gitとの兼ね合い
チーム開発でGitを使っている場合、改行コードの扱いは.gitattributes側でも制御できます。Vim側の設定とGit側の設定が食い違っていると、保存のたびに意図しない差分が発生することがあるので、どちらか一方だけに頼るのではなく両方の設定を一致させておくと事故を防げます。
^M が残る・混ざっているとき
:e ++ff=unix で開き直しても ^M が消えない場合、そのファイルは改行コードが混在しています。Vimは fileformat をファイル全体で1つしか持てないので、途中から形式が変わるファイルはどちらかに寄せるしかありません。
この場合は unix で開いたうえで、残った \r を置換で落とします。
:e ++ff=unix
:%s/\r$// " 行末の CR を消す
:set ff=unix
:w
置換の \r は Ctrl-v Ctrl-m と打っても入力できます。混在したファイルはGitの差分でも扱いにくいので、気づいた時点で寄せてしまうほうが後々楽になります。
自動判定の順番を決める fileformats
開いたときにどの形式と判断するかは fileformats(複数形)の並び順で決まります。既定はUnix系では unix,dos で、まず unix として読み、行末に \r が残るようなら dos と判定し直します。
:set fileformats? " 現在の判定順
set fileformats=unix,dos,mac
ここに mac(CRのみ)を入れると判定の対象が増えますが、そのぶん誤判定も起きやすくなります。実際に古いMac形式のファイルを扱う必要がないなら、入れないほうが安定します。
バイナリモードでは fileformat が効かない
vim -b で開くか set binary を指定すると、fileformat と fileformats は使われなくなります。改行の変換をせずにそのまま読み書きするためで、ファイルを1バイトも変えたくないときの設定です。
そのためバイナリモードでは ^M が必ず見えます。これは異常ではなく、変換していないことの表れです。改行コードを直す作業をするときは、バイナリモードになっていないかを先に確かめてください。
まとめ
改行コードのトラブルはfileformatの仕組みを理解していれば簡単に解決できます。文字コードの扱いとあわせて覚えておくと、環境をまたぐファイル編集で困ることが減ります。文字コードのほうを変えたい場合はfileencodingで、改行コードとは別の設定になります。