Inteligentne zawijanie w Vimie

80

Zastanawiałem się, czy Vim ma możliwość inteligentnego zawijania wierszy kodu, tak aby zachowywał to samo wcięcie co wiersz, który wcina. Zauważyłem to w innym edytorze tekstu, takim jak edytor e-tekstu, i stwierdziłem, że pomogło mi to zrozumieć, na co patrzę.

Na przykład zamiast

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
an example
    </a>
</p>

wyglądałoby jak

<p>
    <a href="somelink">
        This is a bogus link, used to demonstrate
        an example
    </a>
</p>
Sasha
źródło
Zobacz także stackoverflow.com/q/759577/240633
ergosys
Powinieneś ponownie przejrzeć odpowiedzi, gdy sytuacja się zmieniła.
1
Użyj :set autoindenti:set smartindent
Shammel Lee

Odpowiedzi:

62

Ta funkcja została zaimplementowana 25 czerwca 2014 r . W patchu 7.4.338. Nastąpiło kilka poprawek udoskonalających tę funkcję, ostatnia to 7.4.354, więc to jest wersja, którą chcesz.

:help breakindent
:help breakindentopt

Fragmenty pomocy Vima poniżej:

'breakindent'     'bri'   boolean (default off)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Every wrapped line will continue visually indented (same amount of
        space as the beginning of that line), thus preserving horizontal blocks
        of text.

'breakindentopt' 'briopt' string (default empty)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Settings for 'breakindent'. It can consist of the following optional
        items and must be seperated by a comma:
                  min:{n}     Minimum text width that will be kept after
                              applying 'breakindent', even if the resulting
                              text should normally be narrower. This prevents
                              text indented almost to the right window border
                              occupying lot of vertical space when broken.
                  shift:{n}   After applying 'breakindent', wrapped line
                              beginning will be shift by given number of
                              characters. It permits dynamic French paragraph
                              indentation (negative) or emphasizing the line
                              continuation (positive).
                  sbr         Display the 'showbreak' value before applying the 
                              additional indent.
        The default value for min is 20 and shift is 0.

W tym przypadku istotne jest również showbreakustawienie, które doda wielkość zmiany do określonego znaku (ów).

Przykładowa konfiguracja

" enable indentation
set breakindent

" ident by an additional 2 characters on wrapped lines, when line >= 40 characters, put 'showbreak' at start of line
set breakindentopt=shift:2,min:40,sbr

" append '>>' to indent
set showbreak=>>   

Uwaga dotycząca zachowania

Jeśli nie określisz sbropcji, showbreakwszelkie znaki zostaną dołączone do wcięcia. Usunięcie sbrz powyższego przykładu powoduje efektywne wcięcie 4 znaków; z tym ustawieniem, jeśli chcesz używać tylko showbreakbez dodatkowego wcięcia, określ shift:0.

Możesz również wprowadzić przesunięcie ujemne, które spowodowałoby przeciągnięcie showbreakznaków i zawiniętego tekstu z powrotem w dowolne dostępne wcięcie.

Podczas określania minwartości przesunięta kwota zostanie zmniejszona, jeśli szerokość terminala jest węższa, ale showbreakznaki są zawsze zachowane.

Dominykas Mostauskis
źródło
2
Krótko mówiąc, dodanie set breakindentdo konfiguracji vima spowoduje złamanie linii i zawijanie w wcięciu - zamiast przerywać i zaczynać od następnej linii, jakby to była nowa linia.
james2doyle
3
Dodanie set breakindentopt=shift:4do konfiguracji vima spowoduje wcięcie dodatkowych 4 spacji.
fritzo
W tej odpowiedzi pomogłoby dodanie większej liczby przykładów dla breakindentopt. Składnia nie jest oczywista z dokumentu pomocy. Dzięki @fritzo za przykład w komentarzu.
Mnebuerquo,
33

Jest na to łatka, ale trwa od lat i ostatnim razem, gdy sprawdzałem, nie została nałożona czysto. Zobacz wpis „Prawidłowe wcięcie zawiniętych wierszy” na http://groups.google.com/group/vim_dev/web/vim-patches - naprawdę chciałbym, żeby to znalazło się w głównym wierszu.

Aktualizacja: ten link wydaje się być bitrotowany. Oto bardziej aktualna wersja poprawki .

Aktualizacja 2: została scalona w górę (stan na 7.4.345), więc teraz musisz tylko :set breakindent.

ergosys
źródło
Bardzo bym chciał, sprawię, że znaczniki HTML będą bardziej czytelne
Jose Elera
Nie widzę żadnej poprawki na tej stronie. Czy ktoś może potwierdzić?
puk
Najwyraźniej strona została niedawno przebudowana i te linki są zepsute. W tej samej witrynie pojawił się niedawny wpis na blogu z jeszcze nowszą poprawką.
ergosys
1
Tego naprawdę brakuje. Nie rozumiem, dlaczego nie jest to w głównej linii, szczególnie. ponieważ łatka jest bardzo dobrze napisana.
cseelus
2
Dzięki @Vitor Eiji za aktualizację. To świetna wiadomość.
ergosys
17

Nie sądzę, aby można było mieć dokładnie to samo wcięcie, ale nadal można uzyskać lepszy widok, ustawiając opcję „showbreak”.

:set showbreak=>>>

Przykład:

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
>>>an example
    </a>
</p>

Rzeczywistość wygląda lepiej niż powyższy przykładowy kod, ponieważ Vim używa innego koloru dla '>>>'.

za dużo php
źródło
5
możesz również użyć :set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ (kombinacja odwrotnego ukośnika tworzy odstęp między znakami łamania. W ten sposób możesz dodać wystarczająco dużo spacji, aby były głębsze niż większość zawiniętego kodu (np. 10 spacji byłoby głębszych niż 2 tabulatory z czterema spacjami, a 14 byłoby głębsze niż 3 cztery spacje); fajną cechą przestrzeni jest to, że jest mniej rozpraszająca wizualnie (jeśli tego chcesz).
Jeromy Anglim,
7
@Jeromy Anglim Drobna poprawka: set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ jest znacznie mniej czytelna niżlet &showbreak=repeat(' ', 14)
ZyX
8

AKTUALIZACJA: W czerwcu 2014 r. Łatka obsługująca breakindentopcję została włączona do Vima (wersja 7.4.346 lub nowsza dla najlepszego wsparcia).


Możesz też spróbować :set nowrap co pozwoli vimowi wyświetlać długie linie przewijając w prawo. Może to być przydatne do zbadania ogólnej struktury dokumentu, ale może być mniej wygodne w przypadku faktycznej edycji.

Inne opcje zbliżone do tego, czego szukasz, to linebreaki showbreak. Za pomocą showbreakmożesz modyfikować to, co jest wyświetlane na lewym marginesie zawijanych wierszy, ale niestety nie pozwala to na zmienne wcięcie w zależności od bieżącego kontekstu.

Greg Hewgill
źródło
5

Jedynym sposobem, w jaki wiem, że możesz to zrobić, byłoby użycie znaku powrotu (jak wspomniał Cfreak) i połączenie tej textwidthopcji z różnymi opcjami wcięć. Jeśli wcięcie jest skonfigurowane poprawnie (tak jak jest to domyślnie w przypadku składni html, jak sądzę, ale poza tym zobacz opcje autoindenti smartindent), możesz:

:set formatoptions = tcqw
:set textwidth = 50
gggqG

Jeśli dostosujesz formatoptionsustawienia, lepiej po prostu:

:set fo += w
:set tw = 50
gggqG

Co to oznacza:

:set fo+=w  " Add the 'w' flag to the formatoptions so 
            " that reformatting is only done when lines
            " end in spaces or are too long (so your <p>
            " isn't moved onto the same line as your <a...).
:set tw=50  " Set the textwidth up to wrap at column 50
gg          " Go to the start of the file
gq{motion}  " Reformat the lines that {motion} moves over.
G           " Motion that goes to the end of the file.

Zauważ, że to nie to samo, co miękkie zawijanie: zawinie linie w pliku źródłowym, a także na ekranie (chyba że go oczywiście nie zapiszesz!). Istnieją inne ustawienia, które można dodać, formatoptionsktóre będą formatowane automatycznie podczas wpisywania: szczegóły w :help fo-table.

Aby uzyskać więcej informacji, zobacz:

:help 'formatoptions'
:help fo-table
:help 'textwidth'
:help gq
:help gg
:help G
:help 'autoindent'
:help 'smartindent'
DrAl
źródło
3
:set smartindent
:set autoindent

Myślę, że nadal musisz użyć zwrotu

Cfreak
źródło
2

Jeśli twój HTML jest wystarczająco dobrze sformułowany, może pomóc przepuszczenie go przez xmllint :

:%!xmllint --html --format
Arkady
źródło
2

Rozwiązanie makro:


Edytować:

Operacja gq{motion}auto formatuje na dowolną wartość zmiennej "textwidth". Jest to łatwiejsze / lepsze niż użycie opcji 80lBi^MI have dla mojego makra.


Jeśli masz włączone automatyczne wcięcie

:set autoindent

Następnie wprowadzenie zwrotu na końcu wiersza spowoduje wcięcie następnego wiersza o tę samą kwotę. Możesz użyć tego do twardego wpisywania linewraps, jeśli chcesz. Poniższe makro wykorzystuje to do automatycznego wcięcia tekstu:

ustaw rejestr z na:

gg/\v^.{80,}$^M@x (change 80 to whatever length you want your text to be)

i ustaw rejestr x na:

80lBi^M^[n@x (change 80 to whatever length you want your text to be)

Następnie zrób

@x   

aby aktywować makra. Po kilku sekundach cały tekst będzie miał odpowiednio wcięte wiersze o długości maksymalnie 80 znaków.

Wyjaśnienie:

Oto sekcja makr:

Część 1 (makro z):

gg/\v^.{80,}$^M@x

gg - start at the top of the file (this avoids some formatting issues)
/  - begin search
\v - switch search mode to use a more generic regex input style - no weird vim 'magic'
^.{80,}$ - regex for lines that contain 80 or more characters
^M - enter - do the search (don't type this, you can enter it with ctrl+v then enter)
@x - do macro x

Część 2 (makro x):

80lBi^M^[n@x

80l - move right 80 characters
B   - move back one WORD (WORDS include characters like "[];:" etc.)
i^M - enter insert mode and then add a return (again don't type this, use ctrl+v)
^[  - escape out of insert mode (enter this with ctrl+v then escape)
@x  - repeat the macro (macro will run until there are no more lines of 80 characters or more)

Ostrzeżenia:

  • To makro zepsuje się, jeśli istnieje SŁOWO, które ma 80 znaków lub więcej.

  • To makro nie będzie robić inteligentnych rzeczy, takich jak wcięcia wierszy za znacznikami.

  • Użyj ustawienia lazyredraw (: set lazyredraw), aby to przyspieszyć

Michael Asnes
źródło