vim:出现子宏错误后继续宏吗?


14

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

我创建了几个vim宏,分别执行以下步骤:删除尾随的whilespace,删除之后的空行{,删除之前的空行{等。

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

submacro生成错误后,有没有办法使vim宏继续运行?

{1}了解自动重新格式化器。我什至可以在我当前的问题上使用它们。为了示例,我仅提到了源重新格式化。不要发布有关此源美化工具的答案。问题不是关于代码本身的格式化,而是关于vim宏。

例:

  • 宏1-修剪尾随空白- qw/\s\+$d$@wq
  • 宏2-删除}前的空行- qe/\n\n *}dd@eq
  • 包装宏-重新设置标签,宏1,宏2- qr:retab@w@eq

当我执行包装程序时@r,它将重新制表,然后执行宏1,直到找不到更多的尾随空格,然后终止(执行宏2)。

澄清:

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

Answers:


12

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

这是一个愚蠢的例子:

:let @a='f|dt|@a'
:let @q=':try|exe "norm! @a"|endtry^Mj0@q'
@q

包装宏看起来像这样:

let @r=':retab^M:try|exe "norm! @w"|endtry|try|exe "norm! @e"|endtry^M'

尽管加里约翰(Garyjohn)提供了一种解决方法使其在子宏中没有错误,但这是唯一确实能处理此类错误的答案。我不得不道歉。我没有及时检查您的答案,以便您获得(现已过期)赏金... :-(
DevSolar 2011年

25

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

:%s/foo/bar/

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

:%s/foo/bar/e

看到

:help :s_flags

您可以通过在Vim前面加上来告诉Vim忽略某些:ex命令的错误:silent!。看到

:help :silent


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

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

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

qw:%s/\s\+$//^Mq
qe:%s/\n\n *}/\r}/^Mq

其中^M表示输入Enter或Return键。我没有在包装宏中一起测试这些,但是我认为您将能够解决我可能犯的任何错误。


在我来说,这不是替代,而是简单的查找(即/foo)。虽然:silent!递归子宏确实没有终止包装宏的窍门,但现在该子宏根本没有终止……而且我怀疑使其再次终止也将再次终止包装宏。好像我被卡住了。:-\
DevSolar 2011年

在没有看到您正在使用的宏的情况下,或者在出现相同问题的简单示例中,很难说出什么地方出了问题。
garyjohn

添加了一个示例。
DevSolar 2011年

2

对我有用的是@Peter Rincker和@garyjohn答案的组合。另外,我只是不断遇到奇怪的问题。

nnoremap <leader>rt :silent! %s/\s\+$//e<CR>
let @r='\rt'
let @t=':try|silent! exe "norm! @r"|endtry|w^M'

我认为silent!<leader>rt和之间的管道符endtryw人的钥匙-简单地具有后的换行endtry失败。该try帮过当我刚进入其中,但是当宏运行没有找到关于搜索文本错误会继续被提出。


1

当我需要在许多文件中执行重复性任务时,我会即时创建宏。就我而言,我在VIM中安装了NERDtree(http://www.vim.org/scripts/script.php?script_id=1658),这会创建一个vsplit窗口,在左侧,我列出了其中的所有文件当前目录。在一个示例中,我需要MY_TEST在文件中找到字符串的第一个实例,然后删除CUSTOM_PREFIX-该行中标记为的前缀(如果存在),保存文件,然后移至下一个。

这是我在当前目录中的大约2000个文件上使用此宏的方式。我可以编写一个bash脚本来执行此操作,但就我而言,这在VIM中更快。所述+被按压的键表示SIMUL

# Start recording a macro sequence to register 'A'

qa

# Search silently for the string "MY_TEST"; DO NOT report an error
# if the string could not be found.
:silent! /MY_TEST


# Replace, on just the current line, the string "CUSTOM_PREFIX-", with
# nothing (ie: delete it), and suppress any warning messages if the
# string could not be found on the current line.
:s/CUSTOM_PREFIX-//e


# Now issue some UI commands. CTRL-W then and arrow key lets you hope
# between tabs/splits/windows within vim.

CTRL+ W

# Scroll down to the next file in the list in NERDtree



# Open the next file

ENTER

# End the macro

q

# Run the macro a thousand times in VIM

1000 @a

希望这可以帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.