[英]Vim: record macro entering insert mode via mapping
I'm trying to have remap i/c/o/a and friends to always record a macro. 我正在尝试重新映射i / c / o / a和朋友以便始终记录宏。 But the keypress that actually brings me into insert mode is not recorded (explained below).
但实际上将我带入插入模式的按键不会被记录下来(如下所述)。
For example, if we have: 例如,如果我们有:
nnoremap i qzi
inoremap <esc> <esc>q
Ideally, this means that when I enter insert mode ( i
), I also start recording to register z
. 理想情况下,这意味着当我进入插入模式(
i
)时,我也开始录制以注册z
。 And when I leave ( <esc>
), we stop recording. 当我离开(
<esc>
)时,我们停止录音。 So register z should have the entire sequence needed to repeat what I did in insert mode. 因此,寄存器z应该具有重复我在插入模式中所做的所需的整个序列。
But then if I try to type in insert mode (eg, ihelloworld<esc>
) and then check :registers a
, I get 但是如果我尝试输入插入模式(例如,
ihelloworld<esc>
)然后检查:registers a
,我得到
---Registers---
"z helloworld^[
Notice how the i
command is not included -- only what i typed in insert mode is. 注意
i
命令是如何被包含的 - 只有我在插入模式下键入的是。
Why is this happening? 为什么会这样? What can I do to get around it?
我该怎么做才能绕过它?
I also noticed that if I just typed qzihelloworld<esc>
normally, the z
register DOES contain ihelloworld<esc>
(with the i
). 我还注意到,如果我只是正常输入
qzihelloworld<esc>
,那么z
寄存器包含ihelloworld<esc>
(带有i
)。
For those interested, I'm doing trying to do this because certain operations break 'repeat last command (the period key .
)'. 对于那些感兴趣的人,我正在尝试这样做,因为某些操作会破坏'重复最后一个命令(句号键)
.
' For example, if you use <co>
or move around while insert-mode, .
例如,如果您使用
<co>
或在插入模式下移动, .
will only repeat the last segment of your insert mode. 只会重复插入模式的最后一段。 In particular, I'm trying to find a workaround for an autoclosing plugin
特别是,我正在尝试找到一个autoclosing插件的解决方法
As @Carpetsmoker explains why it doesn't get recorded: 正如@Carpetsmoker解释为什么它没有被记录:
The 'q' command is disabled while executing a register, and it doesn't work inside a mapping and :normal.
执行寄存器时禁用'q'命令,它在映射中不起作用,并且:normal。
So that explains why it doesn't work ... 这就解释了为什么它不起作用......
A solution: 一个解法:
As the command (eg, i
) in the mapping is not recorded, a solution is to prepend it to the recorded buffer when leaving insert mode. 由于未记录映射中的命令(例如,
i
),因此解决方案是在离开插入模式时将其预先添加到记录的缓冲区。
To distinguish between i
, a
, o
, etc, you can store the command in a variable, and then prepend that to the recorded macro: 要区分
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>
Simply prepending i
(etc.) to the macro doesn't work (for me) since it triggers the mapping for i
. 简单地将
i
(等)添加到宏中(对我来说)不起作用,因为它触发i
的映射。 Calling it with normal!
normal!
打电话吧normal!
fixes that. 解决了这个问题。
Another option is to modify the macro to enter insert using startinsert
(combined with suitable movements to emulate i
, a
, o
, etc.) by prepending the macro like this 另一种选择是修改宏以使用
startinsert
输入insert(结合适当的动作来模拟i
, a
, o
等),方法是预先设置这样的宏
:let @z=":startinsert^M".@z
caveat: Your rationale for wanting this: 警告:你想要这个的理由:
For example, if you use
<co>
or move around while insert-mode,.
例如,如果您使用
<co>
或在插入模式下移动 ,.
will only repeat the last segment of your insert mode.只会重复插入模式的最后一段。
( my emphasis ) needs the warning that "moving around" (with arrow keys) does not work (at least in my quick tests) without additional hacking, as the arrow keys send an <esc> ...
sequence, triggering the end of the recording mapping for <esc>
. ( 我的重点 )需要警告“移动” (使用箭头键)不起作用(至少在我的快速测试中)没有额外的黑客攻击,因为箭头键发送
<esc> ...
序列,触发结束<esc>
的录制映射。 co
will work though, so you can move around (slowly) with eg <co> h
(for moving left). co
会工作,所以你可以移动(慢慢),例如<co> h
(向左移动)。
Another problem is that replaying it as a macro does not work (with this solution at least, perhaps due to the use of normal!
) if you have newlines, etc., in the recorded macro. 另一个问题是,如果在录制的宏中有新行等,将它重放为宏不起作用(至少使用此解决方案,可能是由于使用了
normal!
)。 A solution to that is to execute
the buffer instead of replaying it as a macro. 解决方案是
execute
缓冲区而不是将其作为宏重放。 That is, :exe @z
instead of @z
for instance with the mapping 也就是说
:exe @z
例如,使用映射来代替:exe @z
而不是@z
nnoremap <space>z :execute @z<cr>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.