Wie kann man lange Schlangen in vim brechen?


12

Ich habe eine ziemlich große Textdatei aus Blöcken wie

Short line.
Really long line.
Short line.

durch leere Zeilen getrennt, und ich möchte vim (unter Linux) verwenden, um die langen Zeilen aufzubrechen und Blöcke wie zu erhalten

Short line.
This was
part of
a long line.
Short line.

Mein Problem mit gq(und gw) ist, dass jeder Block als ganzer Absatz neu ausgeführt wird, dh die beiden Zeilenumbrüche in jedem Block werden nicht beibehalten, und gemäß :help fo-tablekeiner der Formatoptionen kann gqich tun, was ich will. Ich dachte auch, dass ich mein Ziel erreichen könnte, wenn ich neue Zeilenzeichen als Absatzbegrenzer definieren könnte, aber entsprechend :help paragraphsind sie hartcodiert.

Bearbeiten: Ich weiß, dass ich jede lange Zeile einzeln verwenden gqoder gwformatieren kann, aber da meine Datei einige tausend Zeilen umfasst, suche ich nach einer Möglichkeit, dies automatisch zu erreichen.


Übrigens: Ich habe in der Dokumentation von vim nach Lösungen für mein Problem gesucht, hier auf SU und im Internet, die leer sind. Ich werde diese Frage gerne löschen, wenn ich etwas Offensichtliches übersehen habe.
AP


@ MartinSchröder: Schön zu wissen, dass es eine vi SE gibt! Diese Antworten sprechen mein Problem jedoch nicht an, da ich bereits über gqund Bescheid wusste gw. Ich bin auch froh, dass ich hier nicht aufgehört habe, sonst hätte ich nichts über den :gBefehl erfahren . :)
AP

Antworten:


16
:%norm! gww

Dies wendet den normalBefehl gww(der die aktuelle Zeile wie mit formatiert gw) auf den gesamten Puffer an, ohne benutzerdefinierte Zuordnungen zu berücksichtigen (um Probleme zu vermeiden, wenn z. B. gwetwas anderem zugeordnet wurde).

Sehen

  • :help :%
  • :help :norm
  • :help gww

Diese Alternative entspricht dem Vorschlag von Ben in den Kommentaren und ist einfacher als die ursprüngliche Lösung, die unten gespeichert wird, da sie aufgrund der Fähigkeit zum Abgleichen regulärer Ausdrücke unter anderen ähnlichen Umständen möglicherweise besser passt. Im Fall "Alle Zeilen abgleichen" ist dies jedoch unnötig brutal.


Die Anwendung gwwauf jeder einzelnen Zeile im Puffer programmatisch:

:g/^/norm gww

Siehe :help :gund :help norm. ^Entspricht dem Zeilenanfang, wodurch diese in der Praxis mit jeder Zeile übereinstimmt .

Man kann sich auch dafür entscheiden, nur Zeilen auszuwählen, die länger als zB 60 Zeichen sind

:g/\%>60v/norm gww

(siehe :help \%<), aber in der Praxis gwwwerden Zeilen nur länger als textwidthohnehin neu formatiert , sodass es weder für die Geschwindigkeit noch für das Ergebnis von Bedeutung ist.

(Ich verwende vfür "virtuelle Spalte" anstelle von c"Spalte", da letztere tatsächlich eine bestimmte Anzahl von Bytes in der Zeile berechnet. Dies kann zu unerwarteten Ergebnissen führen, wenn Multibyte-Codierungen verwendet werden, was häufig ein Grund zur Vorsicht ist. In der Praxis ist es aus dem gleichen Grund wie oben kein echtes Problem, gwwda dies nicht dazu führt , dass Zeilen kürzer als textwidthohnehin neu formatiert werden.)


Scheitert anscheinend :gohne Muster, :g//norm gwwfunktioniert also nicht, funktioniert aber :g/.*/norm gww.
AP

@AP: Huh, arbeitet für mich. Ich verwende Vim 7.4.488-6 von Debian Unstable.
Daniel Andersson

4
:g//verwendet das letzte Suchmuster wieder; Wenn es keine gibt, schlägt es fehl. Verwenden Sie :g/^/diese Option , um auf alle Zeilen anzuwenden .
Ingo Karkat

@IngoKarkat: Ah, macht Sinn, da mein letztes Muster während der Tests das Zeilenlängen-bewusste war, das ich später demonstrierte. Ich werde die Antwort aktualisieren. Wissen Sie, wo in der Hilfe dieses "leere Muster" -Verhalten erwähnt wird? Ich kann es nicht trivial finden.
Daniel Andersson

Wenn Sie das Handbuch durchsehen, wird wahrscheinlich impliziert, dass die :help last-patternfür die normale Suche angegebenen Informationen auch für den :globalBefehl gelten.
Daniel Andersson

4

Da Sie bereits das Handbuch für die gelesen haben gqund gwBefehle, ich meine , haben Sie wahrscheinlich etwas bequemer wollen als manuell auf die langen Linien zu bewegen und dann mit gw0, gw$oder ein anderer gwBefehl nur die aktuelle Zeile formatiert werden .

Ich kenne keine einfache Möglichkeit, lange Zeilen in Vim über einen Textblock zu brechen. Da Sie jedoch erwähnt haben, dass Sie Vim auf einem GNU / Linux-System verwenden, würde ich vorschlagen, Ihren Text über den fmtBefehl GNU zu filtern .

Für die gesamte Datei:

:%!fmt --width=75 --split-only

Für den aktuellen Absatz (mit kurzen Optionen):

:'{,'}!fmt -75 -s

Erläuterungen zu den relevanten fmtOptionen sind:

  • -w, --width=WIDTH- maximale Zeilenbreite (Standard 75 Spalten). Die Option -WIDTHist eine abgekürzte Form von --width=DIGITS(wenn Sie diese abgekürzte Version verwenden, muss es die erste Option sein).

  • -s, --split-only- lange Schlangen teilen, aber nicht nachfüllen; Dies ist die Option, mit der Ihre bereits vorhandenen Zeilenumbrüche beibehalten werden.


Danke fürs Erwähnen fmt. Ich habe es jedoch vorgezogen, die andere Antwort zu akzeptieren, da sie nur vim erfordert.
AP

@AP Keine Sorge. Es ist eine großartige Antwort und ich hätte sie selbst akzeptiert. Sowohl es als auch Ihre Frage verdienen positive Stimmen.
Anthony Geoghegan

1

Von:

Short line.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Short line.

Setzen Sie den Marker auf die Linie "lorem ipsum" und drücken Sie die gwwAusbeuten ( textwidth=40zur Verdeutlichung):

Short line.
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
Short line.

was mir wie das erscheint, wonach du fragst. Wenn nicht, können Sie dies gerne klären.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.