Perché Vim sta aggiungendo una nuova riga? È una convenzione?


22

Se apro Vim e digito, itest<Esc>:wqottengo un file che non ha nuove righe in Vim ma sembra avere una nuova riga nel codice:

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

Se apro Vim e digito, itest<Return><Esc>:wqottengo un file con una nuova riga in Vim ma due nuove righe nel codice:

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

Si noti che sto aprendo Vim con -u NONEquindi non viene utilizzata alcuna configurazione locale. Si noti inoltre che ciò potrebbe essere correlato a una mia precedente domanda .

Queste sono le informazioni sul mio 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@

Posso confermare lo stesso identico comportamento anche su questo 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@

Perché Vim sta aggiungendo una nuova riga? È una convenzione?

Ecco alcuni chiarimenti sul hdcomando installato su Ubuntu Server:

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

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

8
Sembra essere una convenzione. Ecco come disabilitarlo se lo desideri. Ecco la storia di questo.
jliv902,

Risposte:


28

La convenzione per i file di testo Unix è che ogni riga è terminata da una nuova riga e che le nuove righe sono terminatori di riga, non separatori di riga.

Quando Vim salva un buffer come file, termina ogni riga con la sequenza di fine riga per quel formato di file, che per Unix è una nuova riga. Vedere

:help 'fileformat'

Se stai usando gli strumenti di elaborazione del testo Unix, è meglio attenersi a questa convenzione. Tuttavia, se hai bisogno di non inserire una nuova riga alla fine dell'ultima riga di un file, puoi farlo. Vim considera tali file "binari". Vedere

:help 'binary'
:help edit-binary

1
oh è interessante. Quindi oltre al famoso \ r \ n vs \ n. Windows utilizza i separatori di linea e unix utilizza i terminatori di linea? ed è documentato ovunque? So che qui è definito presumibilmente applicabile a unix "ISO / IEC 9899: 2011, Sezione §7.21.2 I flussi dicono: Un flusso di testo è una sequenza ordinata di caratteri composta in linee, ciascuna linea composta da zero o più caratteri più un nuovo che termina -line character "
barlop

ma dove è documentato che Windows utilizza un separatore di riga?
barlop

2

Vim non sta aggiungendo nulla che tu non abbia messo lì da solo.

Un carattere "newline" non è una "nuova linea" ed entrambi gli esempi sono perfettamente normali:

  • nella prima, il file contiene solo una riga in modo da ottenere un carattere "newline",
  • nella seconda, il file contiene due righe in modo da ottenere due caratteri "newline".

2
Aggiunge la nuova riga. Provalo come segue:, printf "\x41" > /tmp/test.txtquindi controlla che abbia solo un carattere 'A' con xxd /tmp/test.txt. Ora vim /tmp/test.txt<ENTER>:wq. Controlla di nuovo per vedere il file con due byte: 'A \ n'.
Ruslan,

Le linee terminano con un carattere di nuova riga. Hai una riga quindi hai un carattere di nuova riga.
romainl

Bene, dopo printfqui non ho avuto "linee" ben formate. Dopo vim ne ho uno. Quindi, aggiunge qualcosa che non ho messo lì.
Ruslan,

Quello che printfnon sei una linea se non lo aggiungi \n. Essendo un editor di testo, Vim si occupa delle linee per impostazione predefinita e qualsiasi testo che inserisci nel file è almeno una linea, a meno che tu non dica esplicitamente a Vim di non farlo.
romainl

2

I file di testo non terminati sono dannosi per diversi motivi; eccone uno che non ho ancora visto menzionato:

In un mondo ipotetico in cui i file di testo senza una nuova riga finale sono accettabili, non vi sarebbe alcuna differenza tra un file contenente 0 righe e un file contenente 1 riga vuota. Entrambi sarebbero rappresentati da un file a 0 byte.

L'incapacità di decidere quante righe ci sono in un file sarebbe male.


I file di testo nei sistemi non Unix contengono zero o più righe complete, più una riga incompleta di zero o più caratteri. Un file vuoto non contiene una riga vuota; contiene zero righe complete e una riga parziale di zero caratteri. Dov'è l'ambiguità?
supercat,

Questa "linea parziale" è un concetto spiacevole. Non puoi averne uno diverso dalla fine del file e non puoi creare un file che non abbia una "linea parziale". Aggiunge più rotture alla concatenazione dei file - anche se si inserisce una nuova riga tra i file si finisce con qualcosa che non è semanticamente equivalente alla coppia di file originale (perché con 2 file si avevano 2 linee parziali e una di esse è diventata qualcosa diverso.) Una proposta inelegante.

Il fatto che la concatenazione dei file provocherà l'aggiunta di una riga parziale alla fine del primo al file successivo è generalmente dannosa nei casi in cui entrambi i file contengono righe complete (a volte può essere utile concatenare file che non contengono righe complete ), ma è quello che è. Unix non proibisce la costruzione di file di testo che terminano con linee parziali e credo che concatenare tali file si comporterà come in MSDOS. La differenza penso che molti editor basati su DOS abbiano storicamente ritenuto che il caricamento e il salvataggio immediato di un file dovrebbero produrre un nuovo file ...
supercat

... che è un po 'identico a quello precedente (agli utenti registrati delle prime versioni di PC-Write è stato chiesto di usarlo per aprire una copia dell'eseguibile, passare alla modalità di sovrascrittura, trovare una determinata stringa e sostituirla con la loro numero di serie!). Forzare la fine dei file con nuove righe durante il salvataggio violerebbe tale vincolo.
supercat

2

Vim 8.0 ora prevede questo con l' fixeolopzione. In particolare se lo fai:

:set nofixeol

allora Vim non lo farà aggiungerà un carattere di nuova riga finale alla fine della riga finale se il file non ne aveva già uno.

Potrebbe andare in un plugin di tipo di file, o forse anche nel tuo .vimrc .

(Questo è un miglioramento :set binaryperché riguarda solo il carattere di interruzione di riga finale, mentrebinary cambia anche un sacco di altri comportamenti, che probabilmente non vuoi a meno che tu non stia effettivamente modificando un file binario.)

Un file appena creato avrà comunque un carattere di interruzione di riga finale per impostazione predefinita. Puoi cambiarlo (e cambiare un file che ha già una nuova riga finale per non averne uno) facendo inoltre:

:set noeol

Deve essere impostato in modo specifico per ogni file che si desidera modificare: il caricamento di un file in un buffer verrà sempre impostato in modo eolda corrispondere allo stato corrente del file.


1

Usando il comando 'j' puoi unire tutte le linee in una.

Se si desidera rimuovere anche LF o CRLF nell'ultima riga, procedere come segue in vi.

$ vi file
:set binary
:set noeol
:w!
:f          look for [noeol] on the status line
:q
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.