Wie sortiere ich mehrere Textblöcke nach der ersten Zeile in jedem Block in Vim?

11

Ich habe mehrere Textblöcke oder mit anderen Worten mehrere Funktionen wie diese:

def ==(other)
  ...
end

def to_s(full=false)
  ...
end

def to_a
  ...
end

def to_hash
  ...
end

def inspect
  ...
end

Ich möchte die Funktionen alphabetisch nach der Funktionssignatur sortieren. Wie geht das in Vim am einfachsten?

Hubro
quelle
Definieren Sie bitte, was Sie unter Funktionssignatur verstehen. Welche Art von Funktionen sind das? Außerdem wäre es SEHR hilfreich, auf welcher Plattform Sie unter Betriebssystem, Distribution und Versionsnummer arbeiten.
mdpc
1
Warum muss dies in VIM erfolgen? Es gibt ausgezeichnete eingebaute Unix / Linux-Dienstprogramme, die für diese Art von Dingen leicht zusammengeschustert werden können.
Mdpc
@mdpc: Mit der Funktionssignatur meine ich nur die Zeile, die enthält def .... Ich bin unter Linux, daher funktioniert jedes dieser Dienstprogramme für mich.
Hubro

Antworten:

12

Es ist relativ einfach (und, glaube ich, nahe an dem, was Jason vorhatte):

  1. Verwandeln Sie alle Ihre Funktionen in einen Liner, indem Sie alle Zeilenumbrüche durch einen ausgefallenen Charakter ersetzen:

    :g/def/,/end/s/\n/§
    
  2. Sortieren Sie diese Einzeiler mit:

    :%sort
    
  3. Erweitern Sie alle Ihre Funktionen wieder auf ihren ursprünglichen individuellen Zustand:

    :g/def/s/§/\r
    
romainl
quelle
1
In ähnlicher Weise könnte, wenn die Leerzeilen als eindeutige Trennzeichen betrachtet werden können, dies mit :g/./,/^$/-s/\n/§/gund dann :%sortund dann s/§/\r/g
geschehen
3

Ich habe das AdvancedSorters-Plugin geschrieben , um die drei in @ romainls Antwort angegebenen Schritte in einem einzigen Befehl zu vereinfachen:

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

Das Muster hier ist etwas komplexer, um auch die trennenden Leerzeilen richtig einzuschließen.

Ingo Karkat
quelle
Hinweis: Dafür benötigen Sie derzeit ein ziemlich neues Vim 7.4.218. Ich werde in Kürze ein Update bereitstellen, das auch ältere Vim-Versionen unterstützt.
Ingo Karkat
2

Der beste Weg, dies zu tun, ohne eine Funktion zu schreiben, die die Definitionen analysiert, besteht darin, die nicht vorangestellten Zeilenbegrenzer durch ein endanderes eindeutiges Trennzeichen (+ EOL +?) Zu :sortersetzen und dann die Zeilenbegrenzer erneut zu ersetzen. Es könnte wahrscheinlich in einem Makro aufgezeichnet werden.

Eine Funktion ist jedoch möglicherweise besser, wenn Sie die visuelle Auswahl verwenden möchten.

Jason
quelle
2

Probieren Sie das Vissort-Plugin aus. Es unterstützt eine Block-Sortierfunktion:

  • : '<'> BS nextblock endblock findtag tagpat tagsub
  • : [Bereich] BlockSort aufrufen (nextblock, endblock, findtag, tagpat, tagsub)

Wenn Argumente fehlen, werden Sie von BlockSort () danach gefragt. Die Nextblock- / Endblock-Muster begrenzen einen Block. Das Findtag-Muster wird verwendet, um eine Zeile zu finden, die ein "Tag" enthält, das zum Sortieren verwendet wird. Tagpat und Tabsub werden als Ersatz verwendet, um das Sortier-Tag aus der Tag-haltigen Zeile zu extrahieren.

Sie können vissort.vim von http://www.drchip.org/astronaut/vim/index.html#VISSORT erhalten

user21497
quelle