为什么vim粘贴的行为因拉伸方法而异

为什么vim粘贴的行为因拉伸方法而异,vim,paste,yank,Vim,Paste,Yank,我看到不同的粘贴行为取决于我如何拉线。我想知道为什么 如果我从正常模式拉起一条线: ^v$y ^转到行首 v进入视觉模式 $转到行的末尾 y猛拉 然后我使用p进行粘贴,效果如预期 但是,当我从正常模式开始使用视觉模式逐行拉动一条线时: Vy V以逐行转到视觉模式 y猛拉 然后我使用p粘贴,我看到该行粘贴在当前行的下方。这就像粘贴操作是先打开一个新行,然后粘贴到那里 例如。开头的行: Line1 Line2 Line3. Insert here 我用方法1拉扯第2行 我将光标移动到第3行的

我看到不同的粘贴行为取决于我如何拉线。我想知道为什么

如果我从正常模式拉起一条线:

^v$y
^
转到行首

v
进入视觉模式

$
转到行的末尾

y
猛拉

然后我使用
p
进行粘贴,效果如预期

但是,当我从正常模式开始使用视觉模式逐行拉动一条线时:

Vy
V
以逐行转到视觉模式

y
猛拉

然后我使用
p
粘贴,我看到该行粘贴在当前行的下方。这就像粘贴操作是先打开一个新行,然后粘贴到那里

例如。开头的行:

Line1
Line2
Line3. Insert here 
我用方法1拉扯第2行

我将光标移动到第3行的点,然后按
p
进行粘贴。我得到这个结果:

Line1
Line2
Line3.Line2 
 Insert here
Line1
Line2
Line3. Insert here
Line2
但当我用拉金方法2做同样的事情时,我得到了这个结果:

Line1
Line2
Line3.Line2 
 Insert here
Line1
Line2
Line3. Insert here
Line2
如果:寄存器的内容在两种情况下相同,为什么粘贴的效果不同

编辑:

找到了答案

即使寄存器内容相同;寄存器的类型会因拉伸方法的不同而有所不同,不同的寄存器类型会使粘贴做不同的事情。

解释 如果仔细观察,您应该会发现您使用的是
v$
还是
v

:registers ab
--- Registers ---
"a   foo
"b   foo^J
^J
是换行符,表示整行已被拉扯

运动要么影响整行,要么影响起始位置和结束位置之间的字符。在Vim内部,这被称为和characterwise。这同样适用于可视模式(对于
还有第三种模式称为块模式)。所以,你拉东西的方式会有所不同!您可以在
:registers
命令中看到这一点,也可以通过函数查询这一点,但在实践中,这很少令人惊讶(一旦您掌握了这个概念)

使用插件启动 我经常需要将寄存器内容“强制转换”到某种(characterwise/linewise/blockwise)模式,为此我编写了相应的代码。它提供了
gcp
glp
等替代内置粘贴命令的选项,这些命令强制使用特定模式(目前,该主题还有其他一些变体,如使用逗号或查询字符进行粘贴)


有了它,您只需使用
gcp
/
gcp
在光标位置之后/之前粘贴,而不管您如何拖动文本(例如,通过
V
从行视觉模式,如您的问题所示)。因此:

yg_ ................... yank until the last character of the line
OBS:
g
不包括新行字符。有关更多信息,请参见:h g

要选择从行的第一个字符到最后一个字符(不含新行),请执行以下操作:

_vg_

_ ............... jump to the first non-blank char
v ............... visual
g_ .............. las non-blank of the line
找到了答案

即使寄存器内容相同;寄存器的类型会因拉伸方法的不同而有所不同。寄存器类型使粘贴做不同的事情。
您可以通过键入
:echo regtype(“”)来查看给定寄存器的寄存器类型

在我的例子中,我看到两种拉拽方法中的寄存器内容完全相同,包括末尾的回车。如果寄存器内容相同,为什么粘贴工作不同?是否有
:set virtualdit=onemore
?然后将新行包含在
v$y
中。但是,类型仍然相同从字符角度来看,粘贴时,尾随的换行符会出现,但不会在开始处添加新行-这与
Vy
的情况相反。您可以通过
清楚地看到这一点:echo getregtype(“”)
;这就是Vim粘贴类型的基础。
:registers
输出不是100%等效的(但它通常是在不同的情况下)。我没有:set virtualdit=onemore,但我看到的寄存器类型根据拖动方法不同而不同。谢谢你给我指出了正确的方向。啊,很好!您在问题中链接的另一个问题也提到了
getregtype()
,就像我的答案一样。请点击勾选框接受我的回答。这样,问题被标记为已结束,并且您增加了获得未来问题答案的机会,因为这表明您关心答案。