Добавляет ли VIM символы новой строки Windows?

Добавляет ли VIM символы новой строки Windows?

Обратите внимание на окончания строк git diff:

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

Я отредактировал этот файл, поместив курсор на , 1затем нажав ct:и введя новый IP-адрес. Никаких полных строк не было добавлено или удалено из файла. Я заметил, что файл отображается как тип dosв VIM.

Зачем VIM изменил окончание строки, если я явно не редактировал эту часть документа? Кроме того, видя, как diffпоказывает, что в исходной строке не было ^M, как еще VIM мог решить, что это dosфайл?

решение1

Vim определит исходный формат файла (среди настроенных в 'fileformats'), и будет писать в том же формате. Единственный способ для Vim переключиться (например, из Unix в Windows-стиль) — это явно указать :setlocal fileformat=dos. Маловероятно, что у вас это есть в конфигурации; :verbose setl ff?могу вам сказать.

Я бы не стал слишком беспокоиться о самом git diff (если только это невсестроки отображаются как измененные, то на самом деле происходит переключение окончаний строк), а скорее то, что то, что фиксируется, является правильным.

Обратите внимание, что с настройкой Git autocrlf = trueGit преобразует новые строки в системный стандарт при извлечении файлов и в LF-новые строки при фиксации. Так что все может быть просто отлично, только вывод diff Git вас сбивает с толку.

решение2

Это доказательство того, что мы все живем в Матрице. Если бы это был действительно 21-й век, то мы бы не сражались до сих пор с разными окончаниями строк.

Vim отлично справляется с тем, чтобы делать The Right Thing с окончаниями строк. Подробности объясняются в разделе :help 'ffs'. Конечно, vim не может читать ваши мысли: если ваш файл имеетнепоследовательныйокончания строк, то vim может не сделать то, что вам нужно.

Я предлагаю открыть файл в vim, а затем

:e! ++ff=unix

Это перезагрузит файл с диска, заставив vim использовать окончания строк в стиле unix. Затем вы должны увидеть, какие именно строки, любые, имеют окончания CRLF, потому что они будут заканчиваться сырыми ^Mсимволами.

Хотя я и люблю git, я не знаю его и не доверяю ему так же хорошо, как vim. Я думаю, что некоторые люди рекомендуют конфигурации "установил и забыл" для crlfнастроек git, которые могут привести к путанице. Я предпочитаю избегать настройки, которую @Ingo Karkat упомянул в своем ответе. Я хочу, чтобы git извлекал тот же файл, который был извлечён, и позволял мне (и vim) заботиться о окончаниях строк.

решение3

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 ничего не добавляет; тем более не для одной строки. Vim использует окончания строк, которые находит в файле при его открытии.

решение4

Vim на основе значения параметра fileformat определяет, является ли текущий открытый файл файлом dos, unix или mac. Значение параметра fileformat определяется значением параметра fileformats.

Когда vim открывает файл, vim определяет допустимое значение параметра fileformat для текущего буфера на основе значения текущего параметра fileformats. Ниже приведено описание руководства vim о том, как vim определяет значение параметра fileformat текущего буфера по значению параметра fileformats:

'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-файлом, но поскольку этот файл является unix-файлом в дереве индекса git, то, используя git diff, вы увидите, что файл изменился. Для файла в формате Unix дополнительный будет отображаться как символ ^M.

Связанный контент