如何在Vim中每个块的第一行对多个文本块排序?


11

我有多个文本块,或者换句话说,有多个函数,例如:

def ==(other)
  ...
end

def to_s(full=false)
  ...
end

def to_a
  ...
end

def to_hash
  ...
end

def inspect
  ...
end

我想按功能签名的字母顺序对功能进行排序。如何在Vim中最容易做到这一点?


请定义函数签名的含义。这些是什么类型的功能?另外,在操作系统,发行版本和版本号下的哪个平台上运行,将非常有帮助。
mdpc

1
为什么必须在VIM中完成此操作?有出色的内置unix / linux实用程序,可以很容易地将它们拼凑在一起以解决这类问题。
mdpc

@mdpc:通过函数签名,我的意思是包含的行def ...。我在Linux上,因此所有这些实用程序都可以为我工作。
Hubro 2014年

Answers:


12

这是相对简单的(而且我相信与Jason的想法很接近):

  1. 通过用一些花哨的字符替换所有换行符,将所有功能变成一个衬里:

    :g/def/,/end/s/\n/§
    
  2. 用以下方法对那些内衬进行分类:

    :%sort
    
  3. 将所有功能扩展回其初始状态:

    :g/def/s/§/\r
    

1
同样,如果空白行可以被认为是唯一的分隔符,则可以使用:g/./,/^$/-s/\n/§/g,然后使用:%sort,然后使用s/§/\r/g
ArtBIT,

3

我已经编写了AdvancedSorters插件,以将@romainl的答案中给出的三个单独的步骤简化为一个命令:

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

这里的模式稍微复杂一些,也要适当地包含分隔的空行。


注意:您目前需要一个相当新的Vim 7.4.218;我将提供一个更新,该更新也将很快支持较旧的Vim版本。
Ingo Karkat 2014年

2

我可以想到的最好的方法是,不编写解析定义的函数,而是用end另一个唯一的定界符(+ EOL +?)替换之前没有的行定界符,然后:sort再替换行定界符。它可能会记录到宏中。

但是,在您要使用视觉选择的情况下,功能可能会更好。


2

尝试使用vissort插件。它支持块排序功能:

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

如果缺少任何参数,BlockSort()将向您查询。nextblock / endblock模式界定了一个块,findtag模式用于查找包含“ tag”的行,该行将用于排序;使用tagpat和tabsub替代从包含标签的行中提取排序标签。

您可以从http://www.drchip.org/astronaut/vim/index.html#VISSORT获取vissort.vim

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.