我正在使用 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 时,它们起作用了,但是当作为宏运行时,关于未找到搜索文本的错误会不断出现。endtry
w
endtry
try
答案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'
q,a
# 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
希望这可以帮助!