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

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

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

我创建了几个 vim 宏来执行各个步骤:删除尾随空格、删除之后的空行{、删除之前的空行{,诸如此类。

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

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

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

例子:

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

当我执行包装器时 - @r- 它将重新标签,然后执行宏 1,直到不再找到尾随空格,然后终止(没有执行宏2)。

澄清:

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

答案1

我建议您使用它: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'

答案2

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

:%s/foo/bar/

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

:%s/foo/bar/e

:help :s_flags

你可以通过在 :ex 命令前添加 来让 Vim 忽略这些命令的错误:silent!。参见

:help :silent


编辑后在问题中添加示例

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

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

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

其中^M表示键入 Enter 或 Return 键。我尚未在您的 Wrapper Macro 中测试过它们,但我认为您可以修复我可能犯的任何错误。

答案3

对我有用的是@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之间的竖线字符是关键 - 只是在 之后换行失败了。当我直接输入 s 时,它们起作用了,但是当作为宏运行时,关于未找到搜索文本的错误会不断出现。endtrywendtrytry

答案4

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

以下是我让这个宏处理当前目录中大约 2000 个文件的方法。我可以编写一个 bash 脚本来执行此操作,但就我而言,在 VIM 中执行速度更快。+表示同时按下的键

# 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

希望这可以帮助!

相关内容