加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在vim中,寄存器和寄存器之间有什么区别.命令?

发布时间:2020-12-15 21:59:33 所属栏目:安全 来源:网络整理
导读:我很难理解这个 vimgolf challenge的解决方案. 最好的解决方案是 cw(C-RC-P")Escw.w.ZZ 然后我试着去做 cw(C-R")Escw.w.ZZ 但随后文本就变成了 (one) (one)(one) 代替 (one) (two)(three) 有人可以帮助我理解为什么.这两个命令的行为有何不同? 解决方法 由
我很难理解这个 vimgolf challenge的解决方案.

最好的解决方案是

cw(<C-R><C-P>")<Esc>w.w.ZZ

然后我试着去做

cw(<C-R>")<Esc>w.w.ZZ

但随后文本就变成了

(one) (one)
(one)

代替

(one) (two)
(three)

有人可以帮助我理解为什么.这两个命令的行为有何不同?

解决方法

由于接受的答案解决了CTRL-R CTRL-R和CTRL-R CTRL-O之间的差异,但没有回答关于原因的问题.表现得像它一样,文档非常无益,我挖掘了一下源代码.

控制字符

当编辑器遇到控制字符(如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!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读