Jak skonfigurować Vima do pracy z jednym zdaniem w wierszu?

17

Obecnie piszę dużo zwykłego tekstu (i LaTeX-a z minimalnym formatowaniem w akapitach), i byłoby miło, gdybym mógł ustawić vim, aby zachować każde zdanie (dla uproszczenia tekst zakończony znakiem „.”, „!”) lub „?”; jest to kończąca interpunkcja, po której następuje spacja, aby uniknąć łamania liczb dziesiętnych) na jej własnej linii, tak więc różnice VCS będą bardziej przydatne.

Minimalnie chciałbym gqsformatować tekst z:

He lay flat on the brown, pine-needled floor of the forest, his chin on his
folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he
could see the dark of the oiled road winding through the pass. There was a
stream alongside the road and far down the pass he saw a mill beside the
stream and the falling water of the dam, white in the summer sunlight. 

Do:

He lay flat on the brown, pine-needled floor of the forest, his chin on his folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he could see the dark of the oiled road winding through the pass.
There was a stream alongside the road and far down the pass he saw a mill beside the stream and the falling water of the dam, white in the summer sunlight.

Byłoby jednak miło, gdyby vim również wykonywał to formatowanie podczas pisania (podobnie jak w przypadku zmiany przepływu tekstu). czy to możliwe?

Moje obecne rozwiązanie to dołączyć akapit J, a następnie uruchomić, :'<,'>s/\. /.\r/gco jest całkiem dobre, ponieważ jest niewiele wykrzykników i znaków zapytania, ale byłoby znacznie lepiej, gdybym mógł sprawić, że gq będzie nieco mądrzejszy.

Alex
źródło

Odpowiedzi:

23

'formatexpr'opcja

Możesz to osiągnąć za pomocą 'formatexpr'opcji. Z pomocy:

Wyrażenie, które jest przetwarzane w celu sformatowania zakresu linii dla operatora gq lub formatowania automatycznego (patrz „opcje formatowania”). Gdy ta opcja jest pusta, używana jest opcja „formatprg”.

Ustawianie 'formatexpr'poprawnie działa zarówno przy użyciu gqi podczas wstawiania tekstu.

Prosty przykład

Oto prosta funkcja VimScript i odpowiadająca jej 'formatexpr'wartość, która powinna wykonać zadanie. Nie testowałem tego na wszystkich przypadkach, ale działało ładnie w moich prostych testach.

function! MyFormatExpr(start, end)
    silent execute a:start.','.a:end.'s/[.!?]\zs /\r/g'
endfunction

set formatexpr=MyFormatExpr(v:lnum,v:lnum+v:count-1)

Wyjaśnienie

Wyrażenie to wywołanie funkcji MyFormatExpr(), przekazujące linie początkową i końcową, nad którymi zostanie zastosowane formatowanie. Te linie są obliczane przy użyciu automatycznie wypełnianych zmiennych v:lnum(pierwsza linia do sformatowania) i v:count(liczba linii do sformatowania).

MyFormatExpr()Funkcja konstruuje :substitutepolecenia z przekazywane w zasięgu, a zastępuje spacje w następstwie koniec-zdaniu znak interpunkcyjny ( ., !lub ?) z nową linią ( \r).

Ostrzeżenia

  • Ta MyFormatExpr()funkcja nie zachowuje wiodących wcięć. Aby to naprawić, potrzebna byłaby bardziej wyrafinowana logika.
  • Mogą istnieć inne przypadki krawędzi, w których się rozpada. Daj mu jazdę próbną i dostosuj w razie potrzeby!
tommcdo
źródło
Och, tak, to jest kompletna droga, zignoruj moją odpowiedź.
Sukima,
To jest niesamowite! Chciałbym, aby funkcja uruchomiła makro, na przykład „przejdź do następnego zdania )i wstaw nowy wiersz; powtarzaj, aż dojdziesz do końca zakresu”. Wtedy prawdopodobnie zastosowałby wszelkie zasady wcięcia. Ale mój Vim-fu jest na to za słaby. :)
Nathan Long
Dzieje się to np. e.g. blahI Blah et al. 2018jest trochę denerwujące. Możesz dopasować takie wzorce do czegoś podobnego 's/\(e\.g\|\<al\)\@<![.!?]\zs /\r/g'. Po prostu dodaj więcej wzorów do pierwszej grupy, aby uniknąć innych rzeczy, na które nie chcesz się dzielić. W przeciwnym razie jest to bardzo przydatne, dzięki. Nie spotkałem się gqwcześniej i gqipjest bardzo przydatny do formatowania tekstu, który redaktorzy tekstu współautora popsuli.
naught101
Czy istnieje sposób na dodanie tego zachowania do zachowania domyślnego? Chciałbym móc zawijać przy określonej szerokości tekstu, a także dzielić na końcu zdań.
naught101 15.01.19
1

Możesz skonfigurować niektóre mapy i automatyczne polecenia:

function! AddSentenceMaps()
  imap .<Space> .<CR>
  imap !<Space> !<CR>
  imap ?<Space> ?<CR>
  exec "nmap gq vipJ:s/\\([.!?]\\)\\s\\+/\\1\\r/g<CR>"
endfunction

autocmd Filetype customtxt call AddSentenceMaps()

Następnie ustaw typ pliku na customtxt lub wywołaj AddSentenceMapsfunkcję ręcznie.

Sukima
źródło
0

Chcę dodać swoje przemyślenia na temat tego problemu. Zwykle ludzie chcą tego rodzaju funkcji ze względu na przeskakiwanie owiniętych linii podczas nawigacji po kodzie za pomocą poleceń ji k, co jest domyślnym zachowaniem Vima. Do nawigacji po owiniętych liniach używam gj- przesuń w dół i gk- przesuń w górę. Istnieje również możliwość zmiany mapowania standardu ji kkomendy na odpowiedniki z prefiksem g, ale IMHO byłoby przesadą.

Aleksander Myszow
źródło
lub mieć klucz do zrobienia, że remaping z ji kdo gji gkkiedy chcesz ;-)
Anthony
0

Nie odpowiada na konkretne pytanie dotyczące ponownego formatowania, ale „zawijanie zestawu” i „ustawianie podziału linii” mogą znacznie uprzyjemnić edytowanie długich linii. Połącz to z gj i gk, aby poruszać się w zawijanych liniach. Mapuję strzałki w górę i w dół odpowiednio na gj i gk, dzięki czemu mam wybór między przemieszczaniem się w górę i w dół linii rzeczywistych lub linii wizualnych. Jak mądrze dla Home / End do g0 / g $.

Rysował
źródło