¿Por qué Vim agrega una nueva línea? ¿Es esto una convención?

22

Si abro Vim y itest<Esc>:wqescribo, obtengo un archivo que no tiene líneas nuevas en Vim pero parece tener una línea nueva en el código:

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

Si abro Vim y escribo, itest<Return><Esc>:wqobtengo un archivo que tiene una nueva línea en Vim pero dos nuevas líneas en el código:

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

Tenga en cuenta que estoy abriendo Vim con, -u NONEpor lo que no se está utilizando ninguna configuración local. Tenga en cuenta también que esto podría estar relacionado con una pregunta anterior mía .

Esta es la información de mi 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 [email protected]
Compiled by buildd@

Puedo confirmar exactamente el mismo comportamiento en este sistema también:

$ 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 [email protected]
Compiled by buildd@

¿Por qué Vim agrega una nueva línea? ¿Es esto una convención?

Aquí hay algunas aclaraciones sobre el hdcomando instalado en Ubuntu Server:

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

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump
dotancohen
fuente
8
Parece ser una convención. Aquí le mostramos cómo deshabilitarlo si lo desea. Aquí está la historia de esto.
jliv902

Respuestas:

28

La convención para los archivos de texto Unix es que cada línea termina con una nueva línea, y que las nuevas líneas son terminadores de línea, no separadores de línea.

Cuando Vim guarda un búfer como archivo, termina cada línea con la secuencia de fin de línea para ese formato de archivo, que para Unix es una nueva línea. Ver

:help 'fileformat'

Si está utilizando herramientas de procesamiento de texto Unix, es mejor cumplir con esta convención. Sin embargo, si tiene alguna necesidad de no poner una nueva línea al final de la última línea de un archivo, puede hacerlo. Vim considera que dichos archivos son "binarios". Ver

:help 'binary'
:help edit-binary
garyjohn
fuente
1
Oh eso es interesante. Entonces, además del famoso \ r \ n vs \ n. ¿Windows usa separadores de línea y Unix usa terminadores de línea? y eso está documentado en alguna parte? Sé que se define aquí presumiblemente aplicando a unix "ISO / IEC 9899: 2011, la Sección §7.21.2 Secuencias dice: Una secuencia de texto es una secuencia ordenada de caracteres compuestos en líneas, cada línea consta de cero o más caracteres más un nuevo término -line character "
barlop
pero ¿dónde está documentado que Windows usa un separador de línea?
barlop
2

Vim no agrega nada que no hayas puesto allí.

Un carácter de "nueva línea" no es una "nueva línea" y ambos ejemplos son perfectamente normales:

  • en el primero, el archivo solo contiene una línea, por lo que obtienes un carácter de "nueva línea",
  • en el segundo, el archivo contiene dos líneas para que obtenga dos caracteres de "nueva línea".
romainl
fuente
2
Agrega la nueva línea. Pruébelo de la siguiente manera: printf "\x41" > /tmp/test.txtluego verifique que solo tenga un carácter 'A' con xxd /tmp/test.txt. Ahora vim /tmp/test.txt<ENTER>:wq. Verifique nuevamente para ver que el archivo tiene dos bytes: 'A \ n'.
Ruslan
Las líneas terminan con un carácter de nueva línea. Tiene una línea, por lo tanto, tiene un carácter de nueva línea.
romainl
Bueno, después de printfaquí no tuve "líneas" bien formadas. Después de vim tengo uno. Entonces, agrega algo que no puse allí.
Ruslan
Lo que printfno es una línea a menos que agregue \n. Al ser un editor de texto, Vim se ocupa de las líneas de forma predeterminada, y cualquier texto que inserte en el archivo está , como mínimo, en una línea, a menos que le diga explícitamente a Vim que no haga eso.
romainl
2

Los archivos de texto no terminados son malos por múltiples razones; Aquí hay uno que no he visto mencionado todavía:

En un mundo hipotético donde los archivos de texto sin una nueva línea final son aceptables, no habría diferencia entre un archivo que contiene 0 líneas y un archivo que contiene 1 línea en blanco. Ambos estarían representados por un archivo de 0 bytes.

La incapacidad para decidir cuántas líneas hay en un archivo sería mala.


fuente
Los archivos de texto en sistemas que no son Unix contienen cero o más líneas completas, más una línea incompleta de cero o más caracteres. Un archivo vacío no contiene una línea en blanco; contiene cero líneas completas y una línea parcial de cero caracteres. ¿Dónde está la ambigüedad?
supercat
Esta "línea parcial" es un concepto desagradable. No puede tener uno en otro lugar que no sea el final del archivo, y no puede crear un archivo que no tenga una "línea parcial". Agrega más rotura a la concatenación de archivos: incluso si inserta una nueva línea entre archivos, termina con algo que no es semánticamente equivalente al par de archivos original (porque con 2 archivos tenía 2 líneas parciales, y uno de ellos se convirtió en algo diferente.) Una propuesta poco elegante.
El hecho de que la concatenación de archivos haga que cualquier línea parcial al final del primero se anteponga al siguiente archivo es generalmente desagradable en los casos en que ambos archivos contienen líneas completas (a veces puede ser útil concatenar archivos que no contienen líneas completas ), Pero es lo que es. Unix no prohíbe la construcción de archivos de texto que terminen en líneas parciales, y creo que la concatenación de dichos archivos se comportará como en MSDOS. Creo que la diferencia es que muchos editores basados ​​en DOS han considerado históricamente que cargar e inmediatamente guardar un archivo debería producir un nuevo archivo ...
supercat
... que es un poco idéntico al anterior (los usuarios registrados de las primeras versiones de PC-Write recibieron instrucciones de usarlo para abrir una copia del ejecutable, cambiar al modo de sobrescritura, encontrar una cadena determinada y reemplazarla por su ¡número de serie!). Obligar a los archivos a terminar con nuevas líneas al guardarlos violaría esa restricción.
supercat
2

Vim 8.0 ahora proporciona esto con la fixeolopción. Específicamente si haces:

:set nofixeol

entonces Vim no agregará un carácter de línea nueva al final de la línea final si el archivo aún no tiene uno.

Eso podría ir en un complemento de tipo de archivo, o posiblemente incluso en su .vimrc.

(Esta es una mejora :set binaryporque solo afecta el carácter final de salto de línea, mientras que binarytambién cambia un montón de otros comportamientos, que probablemente no desee a menos que esté editando un archivo binario).

Un archivo recién creado seguirá teniendo un carácter de salto de línea final de forma predeterminada. Puede cambiar eso (y cambiar un archivo que ya tiene una nueva línea final a no tener una) haciendo además:

:set noeol

Eso tiene que establecerse específicamente para cada archivo que desea cambiar: cargar un archivo en un búfer siempre se configurará eolpara que coincida con el estado actual del archivo.

Smylers
fuente
1

Usando el comando 'j' puedes unir todas las líneas en una.

Si también desea eliminar el LF o el CRLF en la última línea, haga lo siguiente en vi.

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
Robert
fuente