4

我最喜欢的两个 Vim 特性是能够将标准运算符应用于匹配正则表达式的行,以及通过外部命令过滤选择或范围的行的能力。但是这两个想法可以结合起来吗?

例如,我有一个用作实验室笔记本的文本文件,其中不同日期的笔记由一行破折号分隔。我可以使用类似的东西来删除所有虚线:% g/^-/d。但是假设我想调整所有实际文本行的大小,而不触及那些虚线。

对于单个段落,这将类似于{!}fmt. 但这如何应用于所有非破折号段落?当我尝试看似合乎逻辑的事情,并将这两者与 链接在一起时:% v/^-/!fmt,这是行不通的。(事实上​​,它似乎让 Vim 崩溃了……)

有没有办法将这两个想法联系起来,并且只将匹配模式的行(不)传递到外部命令中,比如fmt

4

2 回答 2

4

考虑该:global命令的工作原理。

:global(and :v) 两次通过缓冲区,

  • 首先标记匹配的每一行,
  • 然后在标记的行上执行给定的命令。

因此,如果你能想出一个命令——无论是 Ex 命令还是命令行工具——以及可以应用于每个匹配行(和范围)的关联范围,你就有了赢家。

例如,假设您的文本是软换行的并且您的段落只是以减号开头的行,以下是重新格式化段落的方法:

:v/^-/.!fmt -72

在这里,我们使用了.“当前行”范围,因此通过fmt过滤了每个匹配的行。更复杂的范围也有效。例如,如果您的文本是硬换行的,并且段落被定义为“从以减号开头的行,直到下一个空白行”,您可以改用:

:g/^-/.,'}!fmt -72

帮助主题:

于 2013-11-07T18:36:36.860 回答
1

一种方法可能是将命令应用于与模式“不只包含破折号”匹配的行

我会尝试的解决方案类似于(未测试):

:g/\v^(-+)@!/normal V!fmt

编辑我正在做一些实验,我认为 recurvie 宏应该适合你

首先设置 nowrapscan:

set nowrapscan

防止递归宏执行超出您的预期。

然后你进行搜索:

/\v^(-+)@!

测试是否按下np与您的模式一起使用,并在需要时对其进行调整

之后,开始录制宏

qqn:.!awk '{print $2}'^M$

在这种情况下,我以 awk 为例,.!表示使用外部程序过滤当前行然后使宏递归只需将字符串附加'@q'到寄存器@q

let @q .= '@q'

并移动到缓冲区的开头以应用递归宏并进行修改:

gg@q

然后你就完成了。希望这可以帮助

于 2013-11-07T01:58:40.467 回答