你如何按长度排序一系列线?

Cor*_*ein 30 regex sorting vim

通常我只想按照#include它们的长度在源文件和头文件的顶部排序.

vim允许我以类似的方式按字母顺序排序:{range} sort u.

vim,如何按行长度对一系列行进行排序?这样较短的线条后面跟着较长的线条.

搜索互联网,我发现了这个:

:% s/.*/\=printf("%03d", len(submatch(0)))."|".submatch(0)/ | sor n | %s/..../
Run Code Online (Sandbox Code Playgroud)

但这只能对整个文件进行排序,无论如何对我来说都是黑魔法.我试图找出如何使用范围从第4行到第18行进行同样的排序,如同:4,18 s/...你有任何想法吗?

Tod*_*obs 27

使用Awk过滤视觉选择

在vim中执行此操作的一种方法是在排序之前使用awk的length()函数过滤视觉选择.例如:

:'<,'> ! awk '{ print length(), $0 | "sort -n | cut -d\\  -f2-" }'
Run Code Online (Sandbox Code Playgroud)

  • @CoryKlein*是*范围.该示例仅使用vim的可视选择(使用`SHIFT-V + <MOTION>`选择的行)指定它.如果你想要行地址,只需将`'<,'>`替换为任何其他有效的地址规范(例如`5,12`). (2认同)

Bir*_*rei 6

一种方式,既不优雅也不高效,但它有效:

将以下功能添加到您的vimrc文件中.它在每行的开头插入其字符数,按数字排序并删除数字.

function! SortLines() range
    execute a:firstline . "," . a:lastline . 's/^\(.*\)$/\=strdisplaywidth( submatch(0) ) . " " . submatch(0)/'
    execute a:firstline . "," . a:lastline . 'sort n'
    execute a:firstline . "," . a:lastline . 's/^\d\+\s//'
endfunction
Run Code Online (Sandbox Code Playgroud)

用一系列数字来称呼它,比如

:4,18call SortLines()
Run Code Online (Sandbox Code Playgroud)

或者在可视模式下使用V,如:

:'<,'>call SortLines()
Run Code Online (Sandbox Code Playgroud)

编辑:Ops,现在我意识到这个解决方案与你的解决方案非常相似.它很好,只是%意味着完整的缓冲区:4,18:'<,:'>选择特定的行.

  • 注意!`strlen()`计算用于表示字符的字节数,因此非ASCII字符可能会出现意外结果.如果你想按显示的长度排序(当涉及<Tab>和双宽度字符时可能会有所不同),最好使用`strchars()`表示字符数,或`strdisplaywidth()`. (4认同)

Ing*_*kat 5

我编写了AdvancedSorters 插件来处理这些复杂的排序要求。

就像@Birei 的回答一样,这个插件提供了扩展命令,可以评估每行一个表达式,将该数字放在该行的前面,进行数字排序,然后再次删除临时数字。专业化处理按字符数和行的显示宽度进行的常见排序,因此您可以使用:

:SortByWidth
Run Code Online (Sandbox Code Playgroud)