Warum fügt Vim eine neue Zeile hinzu? Ist das eine Konvention?

22

Wenn ich Vim öffne und itest<Esc>:wqtippe, erhalte ich eine Datei, die keine Zeilenumbrüche in Vim enthält, aber einen Zeilenumbruch im Code zu haben scheint:

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

Wenn ich Vim öffne und itest<Return><Esc>:wqtippe , erhalte ich eine Datei mit einer neuen Zeile in Vim, aber zwei neuen Zeilen im Code:

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

Beachten Sie, dass ich Vim mit öffne, -u NONEdamit keine lokale Konfiguration verwendet wird. Beachten Sie auch, dass dies mit einer früheren Frage von mir zusammenhängen könnte .

Dies ist meine Systeminfo:

$ 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@

Ich kann das exakt gleiche Verhalten auch auf diesem System bestätigen:

$ 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@

Warum fügt Vim eine neue Zeile hinzu? Ist das eine Konvention?

Hier einige Erläuterungen zum hdBefehl, der auf Ubuntu Server installiert ist:

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

NAME
     hexdump, hd — ASCII, decimal, hexadecimal, octal dump
dotancohen
quelle
8
Es scheint eine Konvention zu sein. Hier erfahren Sie, wie Sie es deaktivieren können, wenn Sie möchten. Hier ist die Geschichte davon.
Jliv902

Antworten:

28

Die Konvention für Unix-Textdateien lautet, dass jede Zeile mit einem Zeilenumbruch abgeschlossen wird und dass Zeilenumbrüche keine Zeilentrennzeichen sind.

Wenn Vim einen Puffer als Datei speichert, wird jede Zeile mit der Zeilenende-Sequenz für dieses Dateiformat beendet, was für Unix ein Zeilenumbruch ist. Sehen

:help 'fileformat'

Wenn Sie Unix-Textverarbeitungstools verwenden, halten Sie sich am besten an diese Konvention. Wenn Sie jedoch eine neue Zeile am Ende der letzten Zeile einer Datei einfügen müssen, können Sie dies tun. Vim betrachtet solche Dateien als "binär". Sehen

:help 'binary'
:help edit-binary
garyjohn
quelle
1
Oh, das ist interessant. Also neben dem berühmten \ r \ n vs \ n. Windows verwendet Zeilentrennzeichen und Unix verwendet Zeilentrennzeichen? und ist das irgendwo dokumentiert? Ich weiß, dass die Definition hier vermutlich für Unix gilt. "ISO / IEC 9899: 2011, Abschnitt §7.21.2 Streams sagt: Ein Text-Stream ist eine geordnete Folge von Zeichen, die in Zeilen zusammengefasst sind, wobei jede Zeile aus null oder mehr Zeichen plus einem abschließenden neuen besteht -line character "
barlop
aber wo ist dokumentiert, dass windows ein zeilentrennzeichen verwendet?
Barlop
2

Vim fügt nichts hinzu, was Sie nicht selbst dort abgelegt haben.

Ein "Newline" -Zeichen ist keine "Newline", und beide Beispiele sind völlig normal:

  • In der ersten Zeile enthält die Datei nur eine Zeile, sodass Sie ein "Newline" -Zeichen erhalten.
  • Im zweiten Fall enthält die Datei zwei Zeilen, sodass Sie zwei "Newline" -Zeichen erhalten.
romainl
quelle
2
Der Zeilenumbruch wird hinzugefügt. Testen Sie es wie folgt: printf "\x41" > /tmp/test.txtund stellen Sie dann sicher, dass es nur ein einziges 'A' Zeichen mit hat xxd /tmp/test.txt. Jetzt vim /tmp/test.txt<ENTER>:wq. Überprüfen Sie erneut, ob die Datei zwei Bytes enthält: 'A \ n'.
Ruslan
Zeilen enden mit einem Zeilenumbruch. Sie haben eine Zeile und somit ein Zeilenumbruchzeichen.
Romainl
Nun, nachdem printfich hier keine wohlgeformten "Linien" hatte. Nach vim habe ich eins. Es fügt also etwas hinzu, das ich nicht dort abgelegt habe.
Ruslan
Was Sie printfnicht eine Zeile ist, wenn Sie anhängen \n. Als Texteditor verarbeitet Vim standardmäßig Zeilen, und jeder Text, den Sie in die Datei einfügen, befindet sich mindestens in einer Zeile, es sei denn, Sie weisen Vim ausdrücklich an, dies nicht zu tun.
Romainl
2

Nicht abgeschlossene Textdateien sind aus mehreren Gründen böse. Hier ist eine, die ich noch nicht gesehen habe:

In einer hypothetischen Welt, in der Textdateien ohne abschließende Zeilenumbrüche zulässig sind, gibt es keinen Unterschied zwischen einer Datei mit 0 Zeilen und einer Datei mit 1 Leerzeile. Sie würden beide durch eine 0-Byte-Datei dargestellt.

Die Unfähigkeit zu entscheiden, wie viele Zeilen sich in einer Datei befinden, wäre schlecht.


quelle
Textdateien in Nicht-Unix-Systemen enthalten null oder mehr vollständige Zeilen sowie eine unvollständige Zeile mit null oder mehr Zeichen. Eine leere Datei enthält keine leere Zeile. Es enthält null vollständige Zeilen und eine Teilzeile mit null Zeichen. Wo ist die Mehrdeutigkeit?
Supercat
Diese "Teillinie" ist ein unangenehmes Konzept. Sie können keine andere Datei als das Ende der Datei erstellen, und Sie können keine Datei erstellen, die keine "Teilzeile" enthält. Die Dateiverkettung wird weiter unterbrochen - selbst wenn Sie zwischen Dateien eine neue Zeile einfügen, erhalten Sie etwas, das semantisch nicht mit dem ursprünglichen Dateipaar übereinstimmt (da Sie bei 2 Dateien 2 Teilzeilen hatten und eine von ihnen zu etwas geworden ist) anders.) Ein uneleganter Vorschlag.
Die Tatsache, dass das Verketten von Dateien dazu führt, dass eine Teilzeile am Ende der ersten bis zur nächsten Datei vorangestellt wird, ist im Allgemeinen schwierig, wenn beide Dateien vollständige Zeilen enthalten (manchmal kann es nützlich sein, Dateien zu verketten, die keine vollständigen Zeilen enthalten ), aber es ist was es ist. Unix verbietet nicht die Erstellung von Textdateien, die mit Teilzeilen enden, und ich glaube, dass sich die Verkettung solcher Dateien wie in MSDOS verhält. Der Unterschied ist meiner Meinung nach, dass viele DOS-basierte Editoren in der Vergangenheit die Ansicht vertreten, dass das Laden und sofortige Speichern einer Datei eine neue Datei ergeben sollte ...
supercat
... das mit dem alten Bit identisch ist (registrierte Benutzer früherer Versionen von PC-Write wurden angewiesen, damit eine Kopie der ausführbaren Datei zu öffnen, in den Überschreibmodus zu wechseln, eine bestimmte Zeichenfolge zu finden und durch ihre zu ersetzen) Ordnungsnummer!). Das Erzwingen von Zeilenumbrüchen beim Speichern von Dateien würde diese Einschränkung verletzen.
Supercat
2

Vim 8.0 bietet hierfür nun die fixeolOption. Wenn Sie Folgendes tun:

:set nofixeol

dann Vim nicht einen nachlauf Newline - Zeichen am Ende der letzten Zeile hinzufügen , wenn die Datei einen nicht bereits hat.

Das könnte in einem Dateityp-Plugin gehen, oder möglicherweise sogar in Ihrem .vimrc.

(Dies ist eine Verbesserung, :set binaryda es sich nur auf das letzte Zeilenumbruchzeichen auswirkt, während sich binaryauch eine Reihe anderer Verhalten ändert, die Sie wahrscheinlich nicht möchten, es sei denn, Sie bearbeiten tatsächlich eine Binärdatei.)

Eine neu erstellte Datei hat weiterhin standardmäßig einen abschließenden Zeilenumbruch. Sie können dies ändern (und eine Datei, die bereits einen letzten Zeilenumbruch enthält, in eine Datei ohne Zeilenumbruch ändern), indem Sie zusätzlich Folgendes ausführen:

:set noeol

Dies muss spezifisch für jede Datei eingestellt werden, die Sie ändern möchten: Das Laden einer Datei in einen Puffer wird immer so eingestellt eol, dass sie dem aktuellen Status der Datei entspricht.

Smylers
quelle
1

Mit dem Befehl 'j' können Sie alle Zeilen zu einer verbinden.

Wenn Sie auch die LF oder CRLF in der letzten Zeile entfernen möchten, gehen Sie in vi wie folgt vor.

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