Por que o Vim está adicionando uma nova linha? Isso é uma convenção?


22

Se eu abrir o Vim e digitar itest<Esc>:wq, recebo um arquivo que não possui novas linhas no Vim, mas parece ter uma nova linha no código:

$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a                    |test.|
00000005

Se eu abrir o Vim e digitar itest<Return><Esc>:wq, recebo um arquivo que possui uma nova linha no Vim, mas duas novas linhas no código:

$ rm test.txt
$ vim -u NONE test.txt
$ cat test.txt | hd
00000000  74 65 73 74 0a 0a                 |test..|
00000006

Observe que estou abrindo o Vim -u NONEpara que não haja nenhuma configuração local sendo usada. Observe também que isso pode estar relacionado a uma pergunta anterior .

Esta é a informação do meu sistema:

$ uname -a
Linux awsAlpha 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:25:35)
Included patches: 1-429
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

Também posso confirmar o mesmo comportamento neste sistema:

$ uname -a
Linux bruno 3.5.0-48-generic #72-Ubuntu SMP Mon Mar 10 23:18:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Oct 26 2012 16:45:33)
Included patches: 1-547
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@

Por que o Vim está adicionando uma nova linha? Isso é uma convenção?

Aqui estão alguns esclarecimentos sobre o hdcomando instalado no Ubuntu Server:

$ man hd | head -4
HEXDUMP(1)            BSD General Commands Manual            HEXDUMP(1)

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump

8
Parece ser uma convenção. Veja como desativá-lo, se quiser. Aqui está a história disso.
— precisa saber é o seguinte

Respostas:


28

A convenção para arquivos de texto Unix é que todas as linhas são encerradas por uma nova linha e que as novas linhas são terminadoras de linha, não separadoras de linha.

Quando o Vim salva um buffer como um arquivo, ele termina todas as linhas com a sequência de fim de linha para esse formato de arquivo, que para o Unix é uma nova linha. Vejo

:help 'fileformat'

Se você estiver usando ferramentas de processamento de texto Unix, é melhor seguir esta convenção. No entanto, se você precisar colocar uma nova linha no final da última linha de um arquivo, poderá fazê-lo. O Vim considera esses arquivos "binários". Vejo

:help 'binary'
:help edit-binary

11
Oh isso é interessante. Então, além do famoso \ r \ n vs \ n. Windows usa separadores de linha e unix usa terminadores de linha? e isso está documentado em algum lugar? Eu sei que é definido aqui, presumivelmente aplicando-se ao unix "ISO / IEC 9899: 2011, Seção §7.21.2. Fluxos diz: Um fluxo de texto é uma sequência ordenada de caracteres compostos em linhas, cada linha composta por zero ou mais caracteres mais uma nova terminação. caractere de linha "
— barlop 23/04

mas onde está documentado que o Windows usa um separador de linhas?
— barlop

2

O Vim não está adicionando nada que você não colocou lá.

Um caractere "nova linha" não é uma "nova linha" e os dois exemplos são perfeitamente normais:

  • no primeiro, o arquivo contém apenas uma linha para que você obtenha um caractere "nova linha",
  • no segundo, o arquivo contém duas linhas para que você obtenha dois caracteres "nova linha".

2
Ele adiciona a nova linha. Teste da seguinte forma: printf "\x41" > /tmp/test.txte verifique se ele possui apenas um caractere 'A' xxd /tmp/test.txt. Agora vim /tmp/test.txt<ENTER>:wq. Verifique novamente para ver o arquivo com dois bytes: 'A \ n'.
— Ruslan #

As linhas terminam com um caractere de nova linha. Você tem uma linha e, portanto, um caractere de nova linha.
— Romainl

Bem, depois printfdaqui eu não tinha "linhas" bem formadas. Depois do vim eu tenho um. Então, adiciona algo que eu não coloquei lá.
— Ruslan

O que você printfnão é uma linha, a menos que acrescente \n. Sendo um editor de texto, o Vim lida com linhas por padrão, e qualquer texto que você inserir no arquivo está em, no mínimo, uma linha, a menos que você diga explicitamente ao Vim para não fazer isso.
— Romainl

2

Arquivos de texto não terminados são ruins por várias razões; aqui está um que eu não vi mencionado ainda:

Em um mundo hipotético em que arquivos de texto sem uma nova linha à direita são aceitáveis, não haveria diferença entre um arquivo contendo 0 linhas e um arquivo contendo 1 linha em branco. Ambos seriam representados por um arquivo de 0 byte.

Incapacidade de decidir quantas linhas estão em um arquivo seria ruim.


Os arquivos de texto em sistemas não-Unix contêm zero ou mais linhas completas, além de uma linha incompleta de zero ou mais caracteres. Um arquivo vazio não contém uma linha em branco; contém zero linhas completas e uma linha parcial de zero caracteres. Onde está a ambiguidade?
— Supercat

Essa "linha parcial" é um conceito desagradável. Você não pode ter um em nenhum outro lugar que não seja o final do arquivo e não pode criar um arquivo que não tenha uma "linha parcial". Ele adiciona mais falhas à concatenação de arquivos - mesmo que você insira uma nova linha entre os arquivos, acabe com algo que não é semanticamente equivalente ao par de arquivos original (porque em 2 arquivos você tinha 2 linhas parciais, e um deles se tornou algo diferente.) Uma proposta deselegante.

O fato de que a concatenação de arquivos fará com que qualquer linha parcial no final do primeiro seja anexada ao próximo arquivo geralmente é nojenta nos casos em que os dois arquivos contêm linhas completas (às vezes pode ser útil concatenar arquivos que não contêm linhas completas ), Mas é o que é. O Unix não proíbe a construção de arquivos de texto que terminem com linhas parciais, e acredito que concatenar esses arquivos se comportará como no MSDOS. A diferença que eu acho é que muitos editores baseados DOS historicamente considerou que o carregamento e imediatamente salvar um arquivo deve render um novo arquivo ...
— supercat

... que é um pouco idêntico ao antigo (os usuários registrados das versões anteriores do PC-Write foram instruídos a usá-lo para abrir uma cópia do executável, alternar para o modo de substituição, encontrar uma determinada string e substituí-la por sua número de série!). Forçar os arquivos a terminarem com novas linhas ao salvá-los violaria essa restrição.
— supercat

2

O Vim 8.0 agora fornece isso com a fixeolopção Especificamente se você fizer:

:set nofixeol

o Vim não adicionará um caractere de nova linha à direita no final da linha final se o arquivo ainda não tiver um.

Isso pode ser feito em um plug-in de tipo de arquivo, ou possivelmente no seu .vimrc.

(Isso é uma melhoria :set binaryporque afeta apenas o caractere final de quebra de linha, enquanto binarytambém altera vários outros comportamentos, que você provavelmente não deseja, a menos que esteja realmente editando um arquivo binário.)

Um arquivo recém-criado ainda terá um caractere de quebra de linha à direita, por padrão. Você pode alterar isso (e mudar um arquivo que já possui uma nova linha final para não ter uma), além de:

:set noeol

Isso deve ser definido especificamente para cada arquivo que você deseja alterar: o carregamento de um arquivo em um buffer sempre será definido eolpara corresponder ao estado atual do arquivo.


1

Usando o comando 'j', você pode juntar todas as linhas em uma.

Se você também deseja remover o LF ou CRLF na última linha, faça o seguinte no vi.

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.