vim:在子宏出错后继续宏?

Dev*_*lar 17 vim macros

我正在使用 vim 美化一些源代码。{1}

我创建了几个执行单独步骤的 vim 宏:删除尾随的 whilespace,删除之后的空行{,删除之前的空行,诸如此类{

现在,我想创建一个按顺序执行所有单个宏的宏。但是,一旦第一个递归宏终止(因为它再也找不到任何匹配项 -> 匹配错误),我的“包装器”宏也会终止。

在子宏产生错误后,有没有办法让 vim 宏继续?

{1}了解自动重新格式化程序。我什至可能会在我当前的问题上使用它们。我只是为了示例而提到了源代码重新格式化。不要发布有关此源美化器或那个的任何答案。问题不在于代码重新格式化本身,而在于 vim 宏。

例子:

  • 宏 1 - 修剪尾随空格 - qw/\s\+$d$@wq
  • 宏 2 - 删除 } 之前的空行 - qe/\n\n *}dd@eq
  • 包装宏 - retabbing,宏 1,宏 2 - qr:retab@w@eq

当我执行包装器时 -@r它会 retab,然后执行宏 1,直到找不到更多的尾随空格,然后终止(执行宏 2)。

澄清:

我正在寻找的是如何调用子宏,以便当该子宏终止时,调用宏会继续?

gar*_*ohn 27

如果失败的命令是找不到其模式的替换,例如,

:%s/foo/bar/
Run Code Online (Sandbox Code Playgroud)

foo缓冲区中不存在时,您可以添加e标志以忽略该错误,例如,

:%s/foo/bar/e
Run Code Online (Sandbox Code Playgroud)

:help :s_flags
Run Code Online (Sandbox Code Playgroud)

你可以告诉 Vim 忽略一些 :ex 命令的错误,在它们前面加上:silent!. 看

:help :silent
Run Code Online (Sandbox Code Playgroud)


在向问题添加示例之后进行编辑

宏 1 和宏 2 都是递归的,并且都没有任何明确的终止递归的机制。我的猜测是 Vim 对无限递归的内部测试之一正在被触发,从而产生错误。如果宏 1 产生了这样的错误,那么该错误将在 之后立即终止包装宏的执行@w

我的建议是通过将宏重写为 :ex 命令并限制执行它们的行范围来限制执行宏的次数。例如:

qw:%s/\s\+$//^Mq
qe:%s/\n\n *}/\r}/^Mq
Run Code Online (Sandbox Code Playgroud)

where^M表示输入您的 Enter 或 Return 键。我还没有在你的 Wrapper Macro 中一起测试过这些,但我认为你可以修复我可能犯的任何错误。


Pet*_*ker 15

我建议您使用:try“吸收”子宏的错误。

这是一个愚蠢的例子:

:let @a='f|dt|@a'
:let @q=':try|exe "norm! @a"|endtry^Mj0@q'
@q
Run Code Online (Sandbox Code Playgroud)

你的包装宏看起来像这样:

let @r=':retab^M:try|exe "norm! @w"|endtry|try|exe "norm! @e"|endtry^M'
Run Code Online (Sandbox Code Playgroud)