Comment trier plusieurs blocs de texte par la première ligne de chaque bloc dans Vim?


11

J'ai plusieurs blocs de texte, ou en d'autres termes, plusieurs fonctions comme celle-ci:

def ==(other)
  ...
end

def to_s(full=false)
  ...
end

def to_a
  ...
end

def to_hash
  ...
end

def inspect
  ...
end

Je veux trier les fonctions par ordre alphabétique selon la signature de la fonction. Comment cela peut-il se faire le plus facilement dans Vim?


définissez ce que vous entendez par signature de fonction, s'il vous plaît. De quel type de fonctions s'agit-il? De plus, sur quelle plate-forme travaillez-vous sous OS, la distribution et le numéro de version seraient TRÈS utiles.
mdpc

1
pourquoi cela doit-il être fait dans VIM? il existe d'excellents utilitaires unix / linux intégrés qui peuvent être facilement bricolés pour ce type de choses .... awk me vient à l'esprit.
mdpc

@mdpc: Par la signature de la fonction, je veux juste dire la ligne contenant def .... Je suis sous Linux, donc l'un de ces utilitaires fonctionnera pour moi.
Hubro

Réponses:


12

C'est relativement simple (et, je crois, proche de ce que Jason avait en tête):

  1. transformez toutes vos fonctions en une seule ligne en remplaçant toutes les nouvelles lignes par un caractère fantaisie:

    :g/def/,/end/s/\n/§
    
  2. trier ces doublures avec:

    :%sort
    
  3. étendez toutes vos fonctions à leur état individuel initial:

    :g/def/s/§/\r
    

1
De même, si les lignes vierges peuvent être considérées comme des séparateurs uniques, cela pourrait être fait avec :g/./,/^$/-s/\n/§/g, puis :%sort, et ensuites/§/\r/g
ArtBIT

3

J'ai écrit le plugin AdvancedSorters pour simplifier les trois étapes distinctes données dans la réponse de @ romainl en une seule commande:

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

Le modèle ici est légèrement plus complexe pour inclure également correctement les lignes vides de séparation.


Remarque: Vous aurez actuellement besoin d'un Vim 7.4.218 assez nouveau pour cela; Je fournirai bientôt une mise à jour qui prend également en charge les anciennes versions de Vim.
Ingo Karkat

2

La meilleure façon de penser à cela sans écrire une fonction qui analyse les définitions, serait de remplacer les délimiteurs de ligne non précédés par endun autre délimiteur unique (+ EOL +?), Puis de :sortremplacer les délimiteurs de ligne. Il pourrait probablement être enregistré dans une macro.

Une fonction pourrait être meilleure cependant, dans le cas où vous souhaitez utiliser la sélection visuelle.


2

Essayez le plugin vissort. Il prend en charge une fonction de tri des blocs:

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

Si des arguments manquent, BlockSort () vous interrogera pour eux. Les modèles de bloc suivant / bloc de fin délimitent un bloc, le modèle findtag est utilisé pour trouver une ligne contenant une "balise" qui sera utilisée pour le tri; tagpat et tabsub sont utilisés dans un substitut pour extraire la balise de tri de la ligne contenant la balise.

Vous pouvez obtenir vissort.vim sur http://www.drchip.org/astronaut/vim/index.html#VISSORT

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.