web-dev-qa-db-ja.com

VIM Windowsの改行を追加していますか?

git diffからの行末に注意してください。

-   IP_ADDR: 'http://1.2.3.4:143'
+   IP_ADDR: 'http://2.4.6.8:143'^M

このファイルを編集するには、カーソルを1に置き、ct:を押して、新しいIPアドレスを入力します。ファイルに完全な行が追加または削除されていません。ファイルがVIMでタイプdosとして表示されていることに気づきました。

ドキュメントのその部分を明示的に編集しなかった場合、なぜVIM行末を変更するのですか?また、diff^Mがないことを示していることを確認してください。元の行、他にどのようにVIMこれがdosファイルであると判断したのでしょうか?

12
dotancohen

Vimは('fileformats'で設定されたものの中から)元のファイル形式を検出し、同じもので書き込みます。 Vimが(たとえば、UnixからWindowsスタイルに)切り替える唯一の方法は、明示的な:setlocal fileformat=dosを使用することです。設定にそれがある可能性は低いです。 :verbose setl ff?が教えてくれます。

私はGitの差分についてあまり心配していません(all行が変更されたように見える限り、実際には行末の切り替えがあります)が、コミットされたものは問題ありません。

Git設定autocrlf = trueを使用すると、Gitはファイルをチェックアウトするときに改行をシステムの標準に変換し、コミットするときにLF改行に変換します。したがって、すべてが問題ない可能性があります。 Gitdiffの出力は混乱を招きます。

10
Ingo Karkat

これは、私たち全員がマトリックスに住んでいる証拠です。これが本当に21世紀だったとしたら、私たちはまだ異なる行末と戦っていないでしょう。

Vimは、行末で正しいことを行うのにかなり良い仕事をしています。詳細は:help 'ffs'で説明されています。もちろん、vimはあなたの心を読み取ることはできません。ファイルにinconsistent行末がある場合、vimはあなたが望むことをしないかもしれません。

ファイルをvimで開いてから開くことをお勧めします

:e! ++ff=unix

これにより、ファイルがディスクからリロードされ、vimはunixスタイルの行末を使用するようになります。次に、生の^M文字で終わるため、CRLFで終わる行を正確に確認する必要があります。

私はgitが大好きですが、vimと同じように、gitを知り、信頼していません。混乱を招く可能性のあるgitのcrlf設定に対して、「設定して忘れる」構成を推奨する人もいると思います。 @IngoKarkatが彼の回答で言及した設定は避けたいと思います。チェックインしたのと同じファイルをgitにチェックアウトさせ、行末を私(およびvim)に任せたい。

6
benjifisher

git diffは、追加された行にキャリッジリターン(^M)のみを表示し、削除された行や変更されていない行には表示しません。 -Rフラグを使用すると、これを確認できます。これは、逆に差分を示します。

$ git diff -R

-   IP_ADDR: 'http://2.4.6.8:143'
+   IP_ADDR: 'http://1.2.3.4:143'^M

したがって、vimは何も追加していません。特に1行だけではありません。 Vimは、ファイルを開いているときに、ファイルで見つけた行末を使用します。

1
Ole

Vimは、fileformatオプションの値に基づいて、現在開いているファイルがdosかunixか、macファイルかを判断します。fileformatオプションの値は、fileformatsオプションの値によって決まります。

Vimがファイルを開くと、vimは現在のfileformatsオプションの値に基づいて、現在のバッファーの有効なfileformatオプション値を決定します。以下は、vimがfileformatsオプションの値によって現在のバッファのfileformatオプションの値を決定する方法についてのvimマニュアルの説明です。

'fileformats' 'ffs' string (default:
                Vim+Vi  MS-DOS, MS-Windows OS/2: "dos,unix",
                Vim Unix: "unix,dos",
                Vim Mac: "mac,unix,dos",
                Vi  Cygwin: "unix,dos",
                Vi  others: "")
            global
            {not in Vi}
    This gives the end-of-line (<EOL>) formats that will be tried when
    starting to edit a new buffer and when reading a file into an existing
    buffer:
    - When empty, the format defined with 'fileformat' will be used
      always.  It is not set automatically.
    - When set to one name, that format will be used whenever a new buffer
      is opened.  'fileformat' is set accordingly for that buffer.  The
      'fileformats' name will be used when a file is read into an existing
      buffer, no matter what 'fileformat' for that buffer is set to.
    - When more than one name is present, separated by commas, automatic
      <EOL> detection will be done when reading a file.  When starting to
      edit a file, a check is done for the <EOL>:
      1. If all lines end in <CR><NL>, and 'fileformats' includes "dos",
         'fileformat' is set to "dos".
      2. If a <NL> is found and 'fileformats' includes "unix", 'fileformat'
         is set to "unix".  Note that when a <NL> is found without a
         preceding <CR>, "unix" is preferred over "dos".
      3. If 'fileformat' has not yet been set, and if a <CR> is found, and
         if 'fileformats' includes "mac", 'fileformat' is set to "mac".
         This means that "mac" is only chosen when:
          "unix" is not present or no <NL> is found in the file, and
          "dos" is not present or no <CR><NL> is found in the file.
         Except: if "unix" was chosen, but there is a <CR> before
         the first <NL>, and there appear to be more <CR>s than <NL>s in
         the first few lines, "mac" is used.
      4. If 'fileformat' is still not set, the first name from
         'fileformats' is used.
      When reading a file into an existing buffer, the same is done, but
      this happens like 'fileformat' has been set appropriately for that
      file only, the option is not changed.
    When 'binary' is set, the value of 'fileformats' is not used.

    When Vim starts up with an empty buffer the first item is used.  You
    can overrule this by setting 'fileformat' in your .vimrc.

    For systems with a Dos-like <EOL> (<CR><NL>), when reading files that
    are ":source"ed and for vimrc files, automatic <EOL> detection may be
    done:
    - When 'fileformats' is empty, there is no automatic detection.  Dos
      format will be used.
    - When 'fileformats' is set to one or more names, automatic detection
      is done.  This is based on the first <NL> in the file: If there is a
      <CR> in front of it, Dos format is used, otherwise Unix format is
      used.
    Also see |file-formats|.
    For backwards compatibility: When this option is set to an empty
    string or one format (no comma is included), 'textauto' is reset,
    otherwise 'textauto' is set.
    NOTE: This option is set to the Vi default value when 'compatible' is
    set and to the Vim default value when 'compatible' is reset.

質問に戻ると、ファイルはvimでdosファイルとして識別されるため、ファイルを保存してvimを終了すると、vimは自動的に改行文字をdosスタイルの改行に置き換えます。

Git作業ディレクトリツリーでは、このファイルはdosファイルですが、このファイルはgitインデックスツリーのunixファイルであるため、git diffを使用すると、ファイルが変更されていることがわかります。 Unix形式のファイルの場合、余分な文字は^ M文字として表示されます。

1
Shaun