重播Vim中的特殊宏

时间:2018-01-23 12:42:58

标签: vim macros

我知道有很多answare重播宏,但我不能让他们在这个特定的宏上工作。

8g8mmxuGojjp`ml

此宏将在文件底部找到下一个非法字符和过去。

8g8 - find the next illegal char.
mm  - mark the spot.
xu  - cut and undo to have the char in the " register.
Go  - jump to the bottom of the file and open a new line.
jj  - my shortcut to exit insert mode.
p   - paste the char.
`m  - jump back to the oreginal location.
l   - move one step to the left. ofherwise 8g8 will just find the same char again...

尝试在entier文件上运行此功能不起作用。

我试过

:%morm! @q

还有视觉选择...

任何想法?

4 个答案:

答案 0 :(得分:2)

首先,它是:norm,而不是:morm

其次,:norm!是非递归的,因此它将jj执行,而不是<Esc>。如果要在宏中使用映射,则需要使用:norm(没有爆炸)。

请参阅:help :normal

答案 1 :(得分:2)

一般来说,这应该有效(忽略你的拼写错误,坚持使用jj映射和:norm!等等,正如其他人已经注意到的那样)。

问题是您通过删除和撤消来获取错误字符的实现。不知何故,Vim在缓冲区的末尾加入粘贴并进行下一次删除,因此您的粘贴会有效消失,就好像它从未发生过一样。 (我仍然看到一些消息表明它正在做这件事,尤其是撤消o命令。)

幸运的是,这可以很容易地避免,因为有一个更好的命令来取消当前角色(没有撤消):yl

这样做(请注意^[是一个文字转义字符,通过<C-V><Esc>插入):

:let @q = '8g8mmylGo^[p`ml'
:%norm! @q

然而,这仍然是不对的。 8g8将移至以下行,因此如果您在每一行上执行此操作,则您将拥有重复项(除非每行都有错误的字符),并且错过后续的错误字符线!

最好通过在末尾添加宏调用来使其成为递归宏

let @q = '8g8mmylGop`ml@q'
:1norm! @q

当您粘贴到缓冲区的末尾时,这些贴片也将由宏处理,可能是无休止的。最好使用大写寄存器来累积寄存器中的坏字符,然后只在宏执行结束时粘贴。我会把它留给你,以便进一步学习: - )

答案 2 :(得分:1)

感谢Ingo,这是解决方案: qaq - 快速清除reg a的方法。 qqq - 快速清除reg q。

8G8&#34; Ayll @ q

8g8 - 找到下一个坏字符。 &#34; Ayl - Yank当前的cher并附加到reg a。 l - 移动到下一个char。 @q - 重复宏。

使用以下命令运行宏: :1norm! @q

最后,所有不好的字符都在reg a。

答案 3 :(得分:0)

为什么你不尝试使用 Esc 代替jj,看看这是否是你的问题?