Jak przełamać długie linie w vimie?

12

Mam dość duży plik tekstowy utworzony z bloków takich jak

Short line.
Really long line.
Short line.

oddzielone pustymi liniami i chciałbym użyć vima (w Linuksie) do podziału długich linii i uzyskania bloków podobnych

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

Mój problem z gq(i gw) polega na tym, że przepełnia każdy blok jako cały akapit, tzn. Nie zachowuje dwóch podziałów wiersza w każdym bloku i zgodnie z :help fo-tableżadną z gqopcji formatu nie pozwala mi robić tego, co chcę. Pomyślałem również, że mógłbym osiągnąć swój cel, gdybym mógł zdefiniować znaki nowej linii jako ograniczniki akapitów, ale zgodnie z :help paragraphnimi są one zakodowane na stałe.

Edycja: Wiem, że mógłbym użyć gqlub gwsformatować każdą długą linię jeden po drugim, ale ponieważ mój plik ma kilka tysięcy wierszy, szukam sposobu na osiągnięcie tego automatycznie.

AP
źródło
Nawiasem mówiąc: szukałem rozwiązania mojego problemu w dokumentacji Vima, tutaj na SU, oraz w Internecie, która wychodzi pusta. Z przyjemnością usunę to pytanie, jeśli przeoczyłem coś oczywistego.
AP
Jest mogę uzasadnić tekst w vim? w vi.sx .
Przywróć Monikę - M. Schröder
@ MartinSchröder: Cieszę się, że istnieje vi SE! Te odpowiedzi nie dotyczą jednak mojego problemu, ponieważ już wiedziałem o gqi gw. Cieszę się również, że nie poprzestałem na tym, bo inaczej nie dowiedziałbym się o :gpoleceniu. :)
AP

Odpowiedzi:

16
:%norm! gww

To stosuje normalpolecenie gww(które formatuje bieżącą linię jak w przypadku gw) do całego bufora, bez uwzględnienia niestandardowych mapowań (aby uniknąć problemów, jeśli np. gwZostał zamapowany na coś innego).

Widzieć

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

Ta alternatywa jest zgodna z sugestią Bena w komentarzach i jest prostsza niż oryginalne rozwiązanie, które zostało zapisane poniżej, ponieważ może pasować lepiej w innych podobnych okolicznościach ze względu na zdolność dopasowywania wyrażeń regularnych. W przypadku „dopasuj wszystkie linie” jest to jednak niepotrzebnie brutalne.


gwwProgramowe zastosowanie do każdej linii w buforze:

:g/^/norm gww

Zobacz :help :gi :help norm. ^dopasowuje początek linii, co w praktyce sprawia, że ​​pasuje do każdej linii.

Można również wybrać tylko linie dłuższe niż np. 60 znaków za pomocą

:g/\%>60v/norm gww

(patrz :help \%<), ale w praktyce gwwformatowanie linii będzie dłuższe niż w textwidthkażdym razie, więc może nie mieć większego znaczenia ani w szybkości, ani w wyniku.

(Używam v„wirtualnej kolumny” zamiast c„kolumny”, ponieważ ta ostatnia naprawdę oblicza pewną liczbę bajtów do linii. Może to prowadzić do nieoczekiwanych wyników przy stosowaniu kodowania wielobajtowego, co często jest powodem do ostrożności. W praktyce nie jest to realny problem z tego samego powodu, co powyżej, ponieważ gwwnie zmieni on formatowania linii krótszych niż w textwidthkażdym razie.)

Daniel Andersson
źródło
Najwyraźniej :gzawodzi bez wzoru, więc :g//norm gwwnie działa, ale :g/.*/norm gwwdziała.
AP
@AP: Huh, działa dla mnie. Używam Vima 7.4.488-6 z Debian Unstable.
Daniel Andersson
4
:g//ponownie wykorzystuje ostatni wzorzec wyszukiwania; jeśli nie ma, to zawiedzie. Użyj, :g/^/aby zastosować do wszystkich linii.
Ingo Karkat
@IngoKarkat: Ach, ma sens, ponieważ mój ostatni wzór podczas testów był świadomy długości linii, którą pokazałem później. Zaktualizuję odpowiedź. Czy wiesz, gdzie w pomocy wspomniane jest zachowanie „pustego wzoru”? Nie mogę go trywialnie znaleźć.
Daniel Andersson
Przeglądając instrukcję, prawdopodobnie sugeruje się, że informacje podane :help last-patternpodczas normalnego wyszukiwania dotyczą również :globalpolecenia.
Daniel Andersson
4

Skoro masz już przeczytać podręcznik dla gqi gwpoleceń, I postać prawdopodobnie chcesz coś bardziej wygodniejsze niż ręczne przenoszenie do długich linii, a następnie przy użyciu gw0, gw$lub innego gwpolecenia tylko sformatować bieżącą linię.

Nie znam łatwego sposobu na łamanie długich linii w Vimie na bloku tekstu. Ponieważ jednak wspomniałeś, że używasz Vima w systemie GNU / Linux, sugeruję filtrowanie tekstu za pomocą fmtpolecenia GNU .

Dla całego pliku:

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

Dla bieżącego akapitu (przy użyciu krótkich opcji):

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

Wyjaśnienie odpowiednich fmtopcji to:

  • -w, --width=WIDTH- maksymalna szerokość linii (domyślnie 75 kolumn). Opcja -WIDTHjest skróconą formą --width=DIGITS(jeśli używasz tej wersji skróconej, musi to być pierwsza opcja).

  • -s, --split-only- podziel długie linie, ale nie uzupełniaj; jest to opcja, która pozwala zachować istniejące wcześniej przerwy w linii.

Anthony Geoghegan
źródło
Dzięki za wzmiankę fmt. Wolałem jednak zaakceptować drugą odpowiedź, ponieważ wymaga ona tylko vim.
AP
@AP Nie martw się. To świetna odpowiedź i sam bym ją zaakceptował. Zarówno to, jak i twoje pytanie zasługują na poparcie.
Anthony Geoghegan
1

Od:

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.

Umieszczanie znacznika na linii „lorem ipsum” i gwwuzyskiwanie wydajności prasowania ( textwidth=40dla większej przejrzystości):

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.

co wydaje mi się tym, o co prosisz. Jeśli nie, prosimy o wyjaśnienie.

Daniel Andersson
źródło