automatycznie zawija wiersze podczas pisania przeceny w VIM

11

Bardzo często piszę przecenę w VIM i będą tam akapity. Aby ułatwić edycję, ustawiam Vima tak, aby zawijał wiersz na 80 znakach. Działa dobrze, jeśli po prostu kontynuuję pisanie, ale problem polega na tym, że jeśli muszę coś poprawić, staje się bardzo denerwujący.

demo (wzięte z logiki pierwszego rzędu wikipedia):

The adjective "first-order" distinguishes first-order logic from higher-order logic 
in which there are predicates having predicates or functions as arguments. In first-order 
theories, predicates are often associated with sets. In interpreted higher-order 
theories, predicates may be interpreted as sets of sets.

Na razie w porządku. Ale kiedy poprawiam artykuł, mogę zdecydować się na dodanie czegoś pośrodku, powiedz:

The adjective "first-order" distinguishes first-order logic from higher-order logic 
in which there are predicates having predicates or functions as arguments,
or in which one or both of predicate quantifiers or function quantifiers are permitted.
In first-order theories, predicates are often associated with sets. In interpreted higher-order
theories, predicates may be interpreted as sets of sets.

zauważ, że linia 3 to ta, którą chcę owinąć. Jeśli zrobię to w VIM, będę musiał ręcznie połączyć linie i zawinąć cały akapit.

Czy ktoś ma pomysł, jak zmusić VIM do robienia tego automatycznie?

Jason Hu
źródło

Odpowiedzi:

7

Jeszcze prostsze: aflaga 'formatoptions'umożliwia automatyczne formatowanie akapitów za każdym razem, gdy tekst jest wstawiany lub usuwany. Zobacz :help fo-tableszczegóły na temat 'formatoptions'flag i :help autoformat.

:set formatoptions+=a

gqi gwsformatuje linie, po których przesuwa się następujący ruch.

Formatting is done with one of three methods:
                1. If 'formatexpr' is not empty the expression is
                   evaluated.  This can differ for each buffer.
                2. If 'formatprg' is not empty an external program
                   is used.
                3. Otherwise formatting is done internally.

                In the third case the 'textwidth' option controls the
                length of each formatted line

Różnica między nimi polega na tym gq, że kursor pozostanie na pierwszym niepustym polu ostatniej sformatowanej linii. gwumieści kursor z powrotem w miejscu, w którym się zaczął.

Możesz łatwo ręcznie ponownie zawinąć akapit, w którym znajduje się kursor gwap, lub cały dokument gggwG, chociaż spowoduje to przesunięcie kursora dzięki prowadzeniu gg.

W przypadku automatycznego polecenia formatowanie może odbywać się automatycznie. Oto przykład, który formatuje bieżący akapit po opuszczeniu trybu wstawiania:

augroup myformatting
    autocmd!
    autocmd InsertLeave * normal gwap<CR>
augroup END

Istnieją inne czynniki uruchamiające automatyczne polecenia, które mogą okazać się dla Ciebie lepsze. Możesz sprawdzić opcje w :help autocmd-events. Te najistotniejsze są prawdopodobnie objęte „różnymi” podpozycjami.

8bittree
źródło
jedno słowo: genialne!
Jason Hu
1

Rzuciłbym okiem :help 'textwidth'. Automatycznie przerywa linie podczas pisania. Jednak to nie działa, jeśli edytujesz środek linii.

Osobiście wolę zrezygnować textwidth, dlatego stworzyłem funkcję, która automatycznie połączy i podzieli akapit. (Zasadniczo formatowanie automatyczne do 80 znaków) Wygląda to tak:

function! ParagraphToEightyChars()
   while (len(getline(".")) > 80)
      normal! 0
      " Find the first white-space character before the 81st character.
      call search('\(\%81v.*\)\@<!\s\(.*\s.\{-}\%81v\)\@!', 'c', line('.'))
      " Replace it with a new line.
      exe "normal! r\<CR>"
      " If the next line has words, join it to avoid weird paragraph breaks.
      if (getline(line('.')+1) =~ '\w')
         normal! J
      endif
   endwhile
   " Trim any accidental trailing whitespace
   :s/\s\+$//e
endfunction

Mam mapowanie, aby móc je wywoływać, gdy tylko będę tego potrzebować:

nnoremap <silent><A-J> :call ParagraphToEightyChars()<CR>

Ta funkcja doskonale formatoptions+=jrnadaje się również do formatowania komentarzy w kodzie! Wystarczy umieścić kursor w pierwszym wierszu dłuższym niż 80 znaków i wywołać funkcję.

(Uwaga: nie podałem tej funkcji do generowania długości innych niż 80, ale myślę, że wystarczy zmienić 80 i 81, jeśli chcesz zrobić coś innego)

Zobacz :help 'textwidth'i :help 'formatoptions'więcej informacji.

Tumbler41
źródło
Dzięki za udostępnienie. Gdy sprawdzam twoją konfigurację, nie formatuje się automatycznie podczas pisania, prawda? Jeśli tak, to nadal nie jest optymalne, prawda?
Jason Hu
textwidthsformatuje się automatycznie podczas pisania. Moja funkcja nie. Wolę kontrolować, kiedy vim owija rzeczy, więc to działa dla mnie. Ale jeśli konkretnie szukasz formatera podczas pisania, tak; nie do końca pasuje do twojego przepływu pracy.
Tumbler41
1

Dla kompletności chciałbym wspomnieć o opcji opartej na wtyczkach.

Jeśli używasz czegoś takiego jak ALE, który obsługuje uruchamianie twoich buforów przez beautifier podczas zapisywania, możesz pozwolić Prettier'owi obsłużyć przepisywanie kodu.

Osiągnąłem to, umieszczając to w ~/.vim/ftplugin/markdown.vim:

let b:ale_fixers = ['prettier', 'remove_trailing_lines', 'trim_whitespace']
let b:ale_javascript_prettier_options = '--prose-wrap always'

... i umieszczając to w ~/.vimrc:

let g:ale_fix_on_save = 1
ssokolow
źródło