O VIM está adicionando novas linhas do Windows?

O VIM está adicionando novas linhas do Windows?

Observe os finais de linha de git diff:

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

Editei este arquivo colocando o cursor 1e pressionando ct:e inserindo o novo endereço IP. Nenhuma linha completa foi adicionada ou removida do arquivo. Percebo, porém, que o arquivo aparece como tipo dosno VIM.

Por que o VIM alteraria o final da linha se eu não editasse explicitamente essa parte do documento? Além disso, vendo como diffmostra que não havia nenhum ^Mna linha original, de que outra forma o VIM poderia ter decidido que se trata de um dosarquivo?

Responder1

O Vim detectará o formato de arquivo original (entre aqueles configurados em 'fileformats') e escreverá com o mesmo. A única maneira de o Vim mudar (por exemplo, do estilo Unix para o estilo Windows) é através de um arquivo :setlocal fileformat=dos. É improvável que você tenha isso em sua configuração; :verbose setl ff?poderia te contar.

Eu não ficaria muito preocupado com o diff do Git (contanto que nãotodoslinhas aparecem como alteradas, então você realmente tem uma mudança de finais de linha), mas sim que o que é confirmado está certo.

Observe que com a configuração do Git autocrlf = true, o Git converterá novas linhas para o padrão do sistema ao fazer check-out de arquivos e para novas linhas LF ao confirmar. Então tudo pode estar bem, apenas a saída diff do Git está confundindo você.

Responder2

Esta é uma evidência de que todos vivemos na Matrix. Se este fosse realmente o século 21, não estaríamos ainda lutando contra diferentes finais de linha.

O Vim faz um ótimo trabalho ao fazer a coisa certa com finais de linha. Os detalhes são explicados em :help 'ffs'. Claro, o vim não pode ler sua mente: se o seu arquivo tiverinconsistentefinais de linha, então o vim pode não fazer o que você deseja.

Sugiro abrir o arquivo no vim e depois

:e! ++ff=unix

Isso irá recarregar o arquivo do disco, forçando o vim a usar finais de linha no estilo unix. Então você deverá ver exatamente quais linhas têm terminações CRLF, porque elas terminarão com ^Mcaracteres brutos.

Embora eu ame o git, não o conheço e confio nele tão bem quanto no vim. Acho que algumas pessoas recomendam configurações do tipo "configure e esqueça" para crlfas configurações do git que podem causar confusão. Prefiro evitar a configuração que @Ingo Karkat mencionou em sua resposta. Quero que o git verifique o mesmo arquivo que foi verificado e deixe que eu (e o vim) cuide dos finais de linha.

Responder3

git diffmostra apenas retornos de carro ( ^M) em linhas adicionadas, mas não em linhas removidas ou inalteradas. Você pode ver isso se usar o -Rsinalizador, que mostra a diferença ao contrário.

$ git diff -R:

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

Então o vim não está adicionando nada; especialmente não para apenas uma linha. O Vim usa os finais de linha que encontra no arquivo ao abri-lo.

Responder4

O Vim é baseado no valor da opção fileformat para determinar se o arquivo atualmente aberto é DOS ou Unix, ou um arquivo Mac. O valor da opção fileformat é determinado pelo valor da opção fileformats.

Quando o vim abre um arquivo, o vim determinará um valor de opção de formato de arquivo válido para o buffer atual com base no valor da opção de formato de arquivo atual. A seguir está a descrição do manual do vim sobre como o vim determina o valor da opção fileformat do buffer atual pelo valor da opção 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.

Voltando à sua pergunta, seu arquivo é identificado como um arquivo dos no vim, então quando você salva o arquivo e sai do vim, o vim substituirá automaticamente o caractere de nova linha pelo estilo dos newline: .

Na árvore de diretórios de trabalho do git, este arquivo é um arquivo dos, mas como esse arquivo é um arquivo unix na árvore de índice do git, então, usando git diff, você verá que o arquivo foi alterado. Para um arquivo no formato Unix, o extra será exibido como caractere ^M.

informação relacionada