Jak posortować wiele bloków tekstu według pierwszego wiersza w każdym bloku w Vimie?

11

Mam wiele bloków tekstu, innymi słowy, wiele funkcji takich jak to:

def ==(other)
  ...
end

def to_s(full=false)
  ...
end

def to_a
  ...
end

def to_hash
  ...
end

def inspect
  ...
end

Chcę posortować funkcje alfabetycznie według sygnatury funkcji. Jak można to najłatwiej zrobić w Vimie?

Hubro
źródło
proszę zdefiniować, co rozumiesz przez podpis funkcji. Jakie to są funkcje? Również na jakiej platformie pracujesz w systemie operacyjnym, pomocna byłaby dystrybucja i numer wersji.
mdpc
1
dlaczego należy to zrobić w VIM? istnieją doskonałe wbudowane narzędzia unix / linux, które można łatwo łączyć ze sobą dla tego typu rzeczy ... awk przychodzi mi na myśl.
mdpc
@mdpc: Przez podpis funkcji rozumiem tylko wiersz zawierający def .... Korzystam z Linuksa, więc każde z tych narzędzi będzie dla mnie działać.
Hubro

Odpowiedzi:

12

Jest to stosunkowo proste (i, moim zdaniem, bliskie temu, co miał na myśli Jason):

  1. zmień wszystkie funkcje w jedną linijkę, zastępując wszystkie nowe wiersze jakimś fantazyjnym charakterem:

    :g/def/,/end/s/\n/§
    
  2. posortuj te wkładki za pomocą:

    :%sort
    
  3. rozwiń wszystkie funkcje z powrotem do ich początkowego stanu indywidualnego:

    :g/def/s/§/\r
    
romainl
źródło
1
Podobnie, jeśli puste linie można uznać za unikalne separatory, można to zrobić za pomocą :g/./,/^$/-s/\n/§/g, a następnie :%sort, a następnies/§/\r/g
ArtBIT
3

Napisałem wtyczkę AdvancedSorters, aby uprościć trzy oddzielne kroki podane w odpowiedzi @ romainl w jednym poleceniu:

:SortRangesByRange /^def\>/,/^end\>\_s*\zs$/

Wzór tutaj jest nieco bardziej skomplikowany, aby poprawnie zawierać również oddzielające puste linie.

Ingo Karkat
źródło
Uwaga: obecnie potrzebujesz do tego całkiem nowego Vima 7.4.218; Niedługo dostarczę aktualizację, która obsługuje również starsze wersje Vima.
Ingo Karkat
2

Najlepszym sposobem, w jaki mogę to zrobić bez napisania funkcji, która analizuje definicje, byłoby zastąpienie ograniczników linii nieprzedstawionych endinnym unikalnym ogranicznikiem (+ EOL +?), A następnie :sortponowne podstawienie ograniczników linii. Prawdopodobnie można go zapisać do makra.

Funkcja może być lepsza w przypadku, gdy chcesz użyć selekcji wizualnej.

Jason
źródło
2

Wypróbuj wtyczkę Vissort. Obsługuje funkcję sortowania bloków:

  • : '<'> BS nextblock endblock findtag tagpat tagsub
  • : [zakres] wywołanie BlockSort (nextblock, endblock, findtag, tagpat, tagsub)

Jeśli brakuje jakichś argumentów, BlockSort () zapyta cię o nie. Wzory nextblock / endblock ograniczają blok, wzorzec findtag służy do znalezienia linii zawierającej „znacznik”, który zostanie użyty do sortowania; tagpat i tabsub są używane w zastępstwie do wyodrębnienia znacznika sortującego z wiersza zawierającego znacznik.

Możesz pobrać vissort.vim z http://www.drchip.org/astronaut/vim/index.html#VISSORT

użytkownik21497
źródło