¿Cómo clasifico varios bloques de texto por la primera línea de cada bloque en Vim?

11

Tengo múltiples bloques de texto, o en otras palabras, múltiples funciones como esta:

def ==(other)
  ...
end

def to_s(full=false)
  ...
end

def to_a
  ...
end

def to_hash
  ...
end

def inspect
  ...
end

Quiero ordenar las funciones alfabéticamente por la firma de la función. ¿Cómo se puede hacer esto más fácilmente en Vim?

Hubro
fuente
define lo que quieres decir con firma de función, por favor. ¿Qué tipo de funciones son estas? Además, en qué plataforma está trabajando bajo el sistema operativo, la distribución y el número de versión serían MUY útiles.
mdpc
1
¿Por qué tiene que hacerse esto en VIM? hay excelentes utilidades incorporadas de Unix / Linux que pueden ser fácilmente ensambladas para este tipo de cosas ... awk viene a la mente.
mdpc
@mdpc: Por la firma de la función me refiero a la línea que contiene def .... Estoy en Linux, por lo que cualquiera de esas utilidades funcionará para mí.
Hubro

Respuestas:

12

Es relativamente simple (y, creo, cercano a lo que Jason tenía en mente):

  1. Convierta todas sus funciones en un solo revestimiento reemplazando todas las líneas nuevas con un carácter elegante:

    :g/def/,/end/s/\n/§
    
  2. ordenar aquellos con los que se recubre:

    :%sort
    
  3. expanda todas sus funciones a su estado individual inicial:

    :g/def/s/§/\r
    
romainl
fuente
1
Del mismo modo, si las líneas en blanco pueden considerarse separadores únicos, entonces podría hacerse con :g/./,/^$/-s/\n/§/g, y luego :%sort, y luegos/§/\r/g
ArtBIT
3

He escrito el complemento AdvancedSorters para simplificar los tres pasos separados dados en la respuesta de @ romainl en un solo comando:

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

El patrón aquí es un poco más complejo para incluir también correctamente las líneas vacías de separación.

Ingo Karkat
fuente
Nota: Actualmente necesitarás un Vim 7.4.218 bastante nuevo para eso; Proporcionaré una actualización que también es compatible con versiones anteriores de Vim pronto.
Ingo Karkat
2

La mejor manera en que puedo pensar en hacer esto sin escribir una función que analice las definiciones, sería sustituir los delimitadores de línea no precedidos por endotro delimitador único (+ EOL +?), Y luego :sort, y volver a sustituir los delimitadores de línea. Probablemente podría grabarse en una macro.

Sin embargo, una función podría ser mejor, en el caso de que desee utilizar la selección visual.

Jason
fuente
2

Prueba el plugin vissort. Es compatible con una instalación de clasificación de bloques:

  • : '<'> BS nextblock endblock findtag tagpat tagsub
  • : [rango] llame a BlockSort (nextblock, endblock, findtag, tagpat, tagsub)

Si falta algún argumento, BlockSort () lo consultará por ellos. Los patrones nextblock / endblock delimitan un bloque, el patrón findtag se usa para encontrar una línea que contenga una "etiqueta" que se usará para ordenar; el tagpat y el tabsub se usan como sustituto para extraer la etiqueta de clasificación de la línea que contiene la etiqueta.

Puede obtener vissort.vim en http://www.drchip.org/astronaut/vim/index.html#VISSORT

usuario21497
fuente