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.