我试图重新映射i / c / o / a和朋友以便始终录制宏。但实际上将我带入插入模式的按键不会被记录下来(如下所述)。
例如,如果我们有:
nnoremap i qzi
inoremap <esc> <esc>q
理想情况下,这意味着当我进入插入模式(i
)时,我也开始录制以注册z
。当我离开(<esc>
)时,我们停止录音。因此,寄存器z应该具有重复我在插入模式中所做的所需的整个序列。
但是如果我尝试输入插入模式(例如ihelloworld<esc>
)然后检查:registers a
,我就会
---Registers---
"z helloworld^[
注意如何不包含i
命令 - 只有我在插入模式下键入的内容。
为什么会这样?我该怎么做才能解决它?
我还注意到,如果我只是正常输入qzihelloworld<esc>
,z
寄存器包含ihelloworld<esc>
(i
)。
对于那些感兴趣的人,我正在尝试这样做,因为某些操作会破坏&#39;重复上一个命令(句号键.
)&#39;。例如,如果您使用<c-o>
或在插入模式下移动,.
将只重复插入模式的最后一段。特别是,我试图找到一个自动关闭插件的解决方法
答案 0 :(得分:3)
@Carpetsmoker解释了为什么它没有录制:
来自:help q
&#39; q&#39;执行寄存器时命令被禁用,它在映射中不起作用,并且:normal。
这就解释了为什么它不起作用......
解决方案:
由于未记录映射中的命令(例如,i
),解决方案是在离开插入模式时将其添加到记录的缓冲区。
要区分i
,a
,o
等,您可以将命令存储在变量中,然后将 添加到录制的宏中:
nnoremap i :let b:mode="i"<cr>qzi
nnoremap a :let b:mode="a"<cr>qza
nnoremap o :let b:mode="o"<cr>qzo
inoremap <Esc> <Esc>q :let @z=":normal! ".b:mode.@z<CR>
简单地将i
(等)添加到宏中(对我来说)不起作用,因为它触发了i
的映射。使用normal!
调用它可以解决问题。
另一种选择是修改宏以使用startinsert
输入插入(结合合适的动作来模拟i
,a
,o
等等。像这样的宏
:let @z=":startinsert^M".@z
警告:您想要这样做的理由:
例如,如果您在插入模式下使用
<c-o>
或移动,则.
将仅重复插入模式的最后一段。
(我的重点)需要警告&#34;移动&#34; (带箭头键)不起作用(至少在我的快速测试中)没有额外的黑客攻击,因为箭头键发送<esc> ...
序列,触发<esc>
的录制映射结束。 c-o
会起作用,所以你可以移动(慢慢地)移动,例如<c-o> h
(左移)。
另一个问题是将它重播为宏不起作用(至少使用此解决方案,可能是由于使用了normal!
)如果您有新行等等,录制的宏。解决方法是execute
缓冲区而不是将其作为宏重放。也就是说,:exe @z
代替@z
,例如映射
nnoremap <space>z :execute @z<cr>