一路阅读完第五章直接跳跃到第十章有关宏的内容,宏的录制和回放功能是多数编辑器都会提供,但我却基本不用这一功能。在 Vim 中宏比点号(.) 更有效的处理重复性操作,既然作为一个 Vimer, 以重复操作为耻,因而十分有必要对它加以了解和掌握的,又是一个一分钟上手需一辈子来掌握的东西。
1. 宏是录制在某个寄存器中,用 q{register}
启动录制,例如 qa
, 然后执行一系操作,再次按 q
结束录制,第一次回放用 @{register}
, 如 @a
,以后多次执行上一次宏回放可用 @@
.也可以支持数字,如 10@a
, 或 10@@
. :reg a
可查看寄存器 a
中宏的内容
2. 录制宏的一条金律是:确保每一条命令是可重复的。h
, j
, k
, l
, 没什么意义,而 0e
, A
, I
就是可重复的。当回放宏时遇到光标移动失败时, 如光标已在行首,宏中有 h
操作,那么后续的操作被放弃,根据 visualbell
配置可能有响声提示。宏的 motion 失败即放弃的特性让我们在重复执行宏时可以用一个足够大的数字,如 200@@
, 反正无副作用
3. 宏的序列执行与并发执行,当用 5@a
执行宏 "a 0f.r)w~j
, 其实是把宏放在一个队列里,往下跳行执行,其他任何一行执行失败,后续行将得不到更新。如果针对宏 "a 0f.r)w~
, 对选择的多行执行 :'<,'>normal @a
时效果就不一样了,它的意思是针对选择的多行单独执行宏,任何行的失败互不影响,所以它是并发执行的
4. 除加命令到已有的宏中,例如我们用 qa
录制了 0f.r)w~
, 保存后意识到少按了一个 j
, 办法是用 qA
, j
, q
就行了,内容变成 0f.r)w~j
。这种办法只能在宏结尾附加命令,修改前面或中间另有他法
5. 针对缓冲区应用宏修改多个文件,打开多个文件的方法可以用 vi *.rb
, 或进到 vi 后执行 :cd ruby_module
, :args *.rb
。现在用 :args
可以看到 [animal.rb] banker.rb frog.rb person.rb
,缓冲取中有这些文件,缓冲区切换可用 :first
, :last
, :prev
, 和 :next
。我们录制一个宏用于裹上模块声明,内容是 "a gg/class^MOmodule Rank^[j>G^[Goend^[
, 现在可用 :argdo
命令对所有缓冲区应用操作,:argdo normal @a
, 为了什么录制宏时的文件不被两次修改,在执行 :argdo
命令之前撤销修改, 命令是 :edit!
, 或 :e !
6. 上面的 :argdo normal @a
对所有缓冲区并行执行了宏,如果要串行执行的话,需在原有宏后加一个 :next
命令,新的宏 a 的内容是 gg/class^MOmodule Rank^[j>G^[Goend^[:next^M
, 这时候可以用 22@a
依次 next 缓冲区应用宏,直接最后停下来。最后多个缓冲区的内容被修改后,要用 :wall
来保存所有文件
7. 利用宏中的 Vim 脚本可以做更有趣的事情,例如给每一行前分别加上序号 1), 2), 3) 等,录制一个宏 I^R=i^M) ^[:let i+=1^M
, 然后选择后序的行执行命令 :'<,'>normal @a
就会为后面的行依次加上 2), 3), 4) 等。有必要说明一下宏里的指令表示法 ^[
是 Esc
, 因为 <C-[
的效果与 Esc
是一样的; ^M
是回车,其他的像 ^R
是 <C-r
8. 自由修改宏的方法是把存储宏的寄存器内容放到缓冲区中,假设录制的 a, :put a
或 :ap
命令可以把宏 a 的内容倒出来。然后编辑它,再存回到相应的寄存器上,命令是 0"ay$
, 如果 "add
或 V"ay
都会在最后加上 ^J
. 因为 0"ay$
是 character-wise 的操作,后两种是 line-wise 的操作,所以会有行尾的 ^J
9. 另外也可以用 Vim script 直接修改宏的内容,如 :let @a=substitute(@a, '\~', 'vU', 'g')
本文链接 https://yanbin.blog/practical-vim-2-notes-4/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。