Como ordeno vários blocos de texto pela primeira linha em cada bloco no Vim?


11

Eu tenho vários blocos de texto ou, em outras palavras, várias funções como esta:

def ==(other)
  ...
end

def to_s(full=false)
  ...
end

def to_a
  ...
end

def to_hash
  ...
end

def inspect
  ...
end

Eu quero classificar as funções em ordem alfabética pela assinatura da função. Como isso pode ser feito mais facilmente no Vim?


defina o que você quer dizer com assinatura de função, por favor. Que tipo de funções são essas? Além disso, em qual plataforma você está trabalhando com SO, distribuição e número da versão seria MUITO útil.
Mdpc

11
por que isso precisa ser feito no VIM? existem excelentes utilitários unix / linux embutidos que podem ser facilmente montados juntos para esse tipo de coisa ... awk vem à mente.
Mdpc

@ MDPC: Pela assinatura da função eu quero dizer a linha que contém def .... Como estou no Linux, qualquer um desses utilitários funcionará para mim.
Hubro 11/05

Respostas:


12

É relativamente simples (e, acredito, próximo ao que Jason tinha em mente):

  1. transforme todas as suas funções em liners, substituindo todas as novas linhas por algum caractere sofisticado:

    :g/def/,/end/s/\n/§
    
  2. classifique esses forros com:

    :%sort
    
  3. expanda todas as suas funções de volta ao seu estado individual inicial:

    :g/def/s/§/\r
    

11
Da mesma forma, se as linhas em branco podem ser considerados como separadores exclusivos, então isso poderia ser feito com :g/./,/^$/-s/\n/§/g, e em seguida :%sort, e depoiss/§/\r/g
ArtBIT

3

Escrevi o plugin AdvancedSorters para simplificar as três etapas separadas fornecidas na resposta do @ romainl em um único comando:

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

O padrão aqui é um pouco mais complexo para incluir também corretamente as linhas vazias de separação.


Nota: No momento, você precisará de um Vim 7.4.218 relativamente novo para isso; Fornecerei uma atualização que também suporta versões mais antigas do Vim em breve.
Ingo Karkat

2

A melhor maneira de pensar em fazer isso sem escrever uma função que analise as definições seria substituir os delimitadores de linha não precedidos por endoutro delimitador exclusivo (+ EOL +?) E, em seguida :sort, substituir novamente os delimitadores de linha. Provavelmente poderia ser gravado em uma macro.

Uma função pode ser melhor, no caso em que você deseja usar a seleção visual.


2

Experimente o plugin vissort. Ele suporta um recurso de classificação de blocos:

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

Se algum argumento estiver faltando, BlockSort () consultará você por eles. Os padrões nextblock / endblock delimitam um bloco, o padrão findtag é usado para encontrar uma linha contendo uma "tag" que será usada para classificação; o tagpat e tabsub são usados ​​em um substituto para extrair a tag de classificação da linha que contém a tag.

Você pode obter o vissort.vim em http://www.drchip.org/astronaut/vim/index.html#VISSORT

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.