排序Vim折叠

时间:2012-11-25 18:43:41

标签: vim

我有一个看起来像这样的文件:

dog{{{
blah blah blah
}}}
cat{{{
blah blah
}}}
aardvark{{{
blah blah blah blah
}}}

在我的vimrc中,我有set foldmethod=marker,因此文件的内容全部折叠在花括号上。我的问题是,如何根据折叠标题对文件进行排序?我希望aarvaark部分先行,然后cat,然后dog

有些折叠部分内有其他折痕。我不想对那些较低的折叠水平进行排序。该文件应按级别1级排序。

4 个答案:

答案 0 :(得分:4)

关闭所有折叠(zM:set foldlevel=0)后,您可以使用删除dd并粘贴p来手动移动折叠的块。对于少量文本,这是可以的。

对于大文本,你必须自己编写一个排序函数,因为Vim不提供这样的功能。可以使用以下算法:

  1. 将所有折叠的行与文本中不存在的分隔符(例如<Nul>)结合在一起。
  2. 执行:sort命令。
  3. 取消加入特殊分隔符的范围。
  4. 对于错误处理和极端情况,它实际上是相当多的实现工作。我在这里尝试过:https://gist.github.com/4145501

答案 1 :(得分:1)

一种方法如下:

  1. 搜索并替换行结尾,以便一级折叠各自在一行上(即替换以文件中未出现的唯一字符串结尾的行)。

    < / LI>
  2. 照常使用:sort对文件中的行进行排序。

  3. 撤消搜索并从步骤1替换以重新引入行结尾。

  4. 这可以全部记录为Vim宏。

    如果没有嵌套折叠,或者如果有一种简单的方法可以区分顶级折叠和嵌套折叠(例如,如果一级{{{和}}}行是,那么步骤1和3将是直截了当的向左冲,其他人有领先空间)。如果情况并非如此,那可能仍然有可能,但要困难得多。

答案 2 :(得分:1)

我会使用Vim宏的力量。

假设您的文件中没有任何其他人员,除了记录和第一行记录从第一行开始。并且你没有1级的开始并且在同一行结束。你的所有{}都很好。

转到第一个条目并录制一个宏来注册(qa - 开始录制q - 停止)

/{^MV%k:s/\n/EEEEEE/^Mj^

复制我的或者更好地自己录制:(^ M - 代表文字输入)

  • / {^ M找到下一个{
  • V%k选择直线电视直至1级结束,但不选择结束线}}}
  • :s / \ n / EEEEEE / ^ M将符号'行尾'更改为选择中的某个唯一字符串
  • j ^如果前一条记录有前导空格,则向下一行并向该行的乞讨。

从第二行开始运行宏(假设在录制宏时已经处理了第一行。) 在正常模式下100000 @ a - 使用大于您的记录数的任何数字。如果第一个记录位于文件的第一行,则处理所有行时宏将自行停止。作为副作用,它将在视觉上选择第一行 - 取消选择它。

对文件进行排序

:sort

恢复行尾: :%S / EEEEEE / ^ M / G

注意^ M应该是文字输入。要输入它,请使用Ctrl-V Enter

它适用于嵌套级别,因为%会跳转到匹配的结束}。这就是为什么让所有{}匹配好的重要原因。

k无法使用时,宏将停止,这就是为什么你必须在第一行有第一条记录。宏将忽略空行或记录之间没有记录的任何内容。

上述方法适用于您的文件。如果你想要一个更通用的折叠方法,那么在宏中使用以下命令而不是/ {和%

首先打开所有折叠

zj - 转到下一个开放折叠的开头

] z - 转到当前折叠的末尾。

宏的其余部分是相同的。 这种方法比较通用,但我发现它不太可靠,因为它取决于所有折叠打开,折叠启用等等。

答案 3 :(得分:0)

有一个专门为此制作的vim-sort-folds插件。