最好的解决方案是
cw(<C-R><C-P>")<Esc>w.w.ZZ
然后我试着去做
cw(<C-R>")<Esc>w.w.ZZ
但随后文本就变成了
(one) (one) (one)
代替
(one) (two) (three)
有人可以帮助我理解为什么.这两个命令的行为有何不同?
解决方法
控制字符
当编辑器遇到控制字符(如CTRL-H
)时,它会执行命令(在本例中为退格),而不是插入该字符.所以在插入模式下,
Hello<CTRL-H>World
产量
HellWorld
但是,如果控制字符前面有CTRL-V,则文字控制字符将作为文本插入.从而,
Hello<CTRL-V><CTRL-H>World
给我们
Hello^HWorld
其中^ H实际上只是用CTRL-H得到的角色的表示.
控制角色
因此,如果你想从字面上插入寄存器中的文本,你怎么能只使用CTRL-R呢?好吧,CTRL-R插入文本就像输入一样.但这意味着我们可以使用CTRL-V来诱骗Vim模拟CTRL-R CTRL-R!假设我们要插入的文本在第1行:
1| Hello^HWorld
如果我们只是把它放在插入模式,我们将有一个糟糕的时间:
"ay$o <CTRL-R>a --> 2| HellWorld
相反,让我们先插入^ V:
:s/<CTRL-V><CTRL-H>/<CTRL-V><CTRL-V>& "ay$o <CTRL-R>a --> 2| Hello^HWorld
这给了我们Hello ^ HWorld,就像我们想要的那样.
直接插入
现在你基本知道CTRL-R CTRL-R是如何工作的 – 它在每个字符之前插入^ V,确保每个字符都按字面插入而不是像输入一样.
插入模式使用vgetorpeek
读取字符.这有三个部分,我们可以简化为两个部分:
>尝试从填充缓冲区中获取角色.
>如果填充缓冲区为空,则从用户处获取一个字符.
当您按CTRL-R或CTRL-R CTRL-R时,这将调用insert_reg
.该函数将寄存器的内容插入填充缓冲区,因此Vim将读取它,就好像它正在键入一样.
在CTRL-R CTRL-R的情况下,我们在每个特殊字符之前将insert CTRL-V
放入填充缓冲区(除了Tab **).所以,这与使用我们的正则表达式和单独的CTRL-R没有什么不同 – 只是更方便.
CTRL-R CTRL-O和.命令
故事的道德,当你使用CTRL-R [CTRL-R]时,.命令只会看到您键入的文本流.
但是CTRL-R CTRL-O和CTRL-R CTRL-P的故事完全不同,这显然是在Bram fixed a bug where pasting with the mouse wasn’t repeated properly by .
时添加的.我们调用do_put
而不是使用insert_reg,它直接将寄存器的内容放入文本中,不要传递Go,不要解释关键序列.
一个结果(Bram的用途)是Tabs,即使用CTRL-R CTRL-R也不按字面插入,用CTRL-R CTRL-O字面插入.用visible whitespace在家里试试.我认为这就是神秘的“不替换角色!” line in:help means.
但更有趣的副作用是寄存器的值不会出现在重做缓冲区中 – 就像我们从未输入过一样.相反,Bram会手动调用AppendCharToRedobuff这样做.将重复使用CTRL-R CTRL-O!
/* Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r */ AppendCharToRedobuff(Ctrl('R')); AppendCharToRedobuff(fix_indent ? Ctrl('P') : Ctrl('O')); AppendCharToRedobuff(regname == 0 ? '"' : regname);
老实说,这似乎是一个懒惰的解决方案,甚至可能是一个错误.但结果是,每次重复时,可以使用CTRL-R CTRL-O引入寄存器并获取寄存器的内容.
这就是为什么你会看到不同的行为:
1| one two 2| three cw(<C-R><C-P>")<Esc>w.w. 1| (one) (two) 2| (three)
当重复这一过程时,cw更新“注册为”两个“,然后”三个“,并且< C-R>< C-P>”来了,重新读了“寄存器.
如果我们只使用< C-R>“(或< C-R>< C-R>”,这在这里没有区别),重复该动作只重复插入“一”.
cw(<C-R>")<Esc>w.w.ZZ 1| (one) (one) 2| (one)
你可以看到差异.通过使用注册:reg.每个版本之后,虽然我不确切知道如何.寄存器对应于.行动.
**这解释了其他一些奇怪的东西.如果您键入< CTRL-V>< Tab>在插入模式下,即使你有:set expandtab,你也会得到一个标签,因为< CTRL-V>强制文字制表符.
但是,如果您将Something< CTRL-V>< Tab> Something拉入寄存器,然后尝试使用< CTRL-R>< CTRL-R>插入它,则选项卡会扩展为空格,就像您有仅使用< CTRL-R>.这由stuffescaped
function解释,无论出于何种原因,它都不插入< CTRL-V>在标签之前.
由于< CTRL-R>< CTRL-O>不需要< CTRL-V> (实际上会将那些插入文字^ V字符!)标签保持不变 – 或者像Bram所说的那样,
Does not replace characters!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。