分类Vim折叠

16

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

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

在我的vimrc中,我有set foldmethod=marker,这样文件的内容就都折叠在花括号中了。我的问题是,如何根据折叠标头对文件进行排序?我希望将aarvaark部分放在首位,然后是cat,再接下来是dog

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

4个回答

5

当所有折叠都关闭(zM:set foldlevel=0)时,您可以使用删除dd和粘贴p来手动移动折叠块。这对于少量文本来说还好。

对于大量文本,您需要自己编写排序函数,因为Vim不提供此功能。可以使用以下算法:

  1. 使用不存在于文本中的分隔符(例如<Nul>)将所有折叠行连接在一起。
  2. 执行:sort命令。
  3. 在特殊分隔符上取消连接范围。

实际上,这需要处理错误和边角情况,需要相当多的实现工作。我在这里尝试了一下:https://gist.github.com/4145501


1

我会使用 Vim 宏的功能。

假设您的文件中除了记录以外没有其他内容,并且第一条记录从第一行开始。并且您没有在同一行上开头和结尾的级别 1 开始。并且所有的 {} 都匹配。

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

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

复制我的指令或者自己录制:

  • /{^M 查找下一个 {
  • V%k 选择从当前行到第一层级结束但不包括 }}}} 的所有行
  • :s/\n/EEEEEE/^M 将选中区域内的换行符替换为独特的字符串
  • j^ 移动到下一行并回到行首,以防前一条记录有前导空格。

从第二行开始运行宏(假设第一行已经处理完毕)。在正常模式下输入100000@a - 使用大于您记录数的任何数字。当所有行都被处理完毕时,宏将自动停止。作为副作用,它会可视化选择第一行并取消选择。

对文件进行排序。

:sort

恢复行尾:

:%s/EEEEEE/^M/g

注意:^M应该是字面意义上的回车符。要输入它,请使用Ctrl-V Enter。

它适用于嵌套级别,因为%跳转到匹配的闭合}。这就是为什么重要的是您要确保所有{}匹配良好。

当宏无法使用k向上移动时,宏将停止,因此您必须将第一条记录放在第一行。空行或任何不是记录的内容都将被宏忽略。

上述方法应该适用于您的文件。如果您想要更通用的折叠方法,则可以在宏中使用以下命令,而不是/{和%:

首先打开所有折叠

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

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

其余的宏是相同的。 这种方法更通用,但我发现它不太可靠,因为它依赖于所有折叠的打开,折叠启用等等。


1

一种方法如下:

  1. 搜索并替换行尾,使得每个一级折叠都在一行上(即用一个在文件中没有出现过的唯一字符串替换行尾)。

  2. 使用 :sort 命令按照惯例对文件中的行进行排序。

  3. 反向执行第 1 步的搜索和替换操作,以重新引入行尾。

这些步骤可以全部记录为 Vim 宏。

如果没有嵌套折叠,或者有一种简单的方法来区分顶层折叠和嵌套折叠(例如,如果一级 {{{ 和 }}} 行左对齐,而其他行有前导空格),那么步骤 1 和 3 将是直接的。如果不是这种情况,可能仍然是可能的,但要困难得多。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接