ChatGPT解决这个技术问题 Extra ChatGPT

Vim:用之前拉过的另一条线替换一条线

vim

每天至少一次我有以下情况:

A: This line should also replace line X
...
X: This is line should be replaced

我相信我不能有效地完成这项任务。

我所做的:

前往 A 行:AG

拉线A:yy

转到第 X 行:XG

粘贴线A:P

移至旧行:j

删除旧行:dd

这还有一个额外的缺点,即第 X 行现在位于默认寄存器中,如果我发现另一行应该用 A 替换,这很烦人。从一个额外的寄存器(“ayy,”aP)中提取和粘贴使这个简单的任务变得更简单效率较低。

我的问题:

我是否错过了一个内置的 Vim 命令来替换之前被拉出的行?

如果没有,我如何绑定我自己的命令,在默认寄存器中留下(或恢复)被拉出的行?

这是我对 Vim 编辑模型的最大问题。我很想知道一个解决方案。 CUA 编辑器区分剪切和删除,因此您只需剪切一些文本,然后您可以删除并粘贴您想要的所有内容。使用 Vim,你所做的任何删除都会破坏你的剪切文本。您最终会使用比其他编辑器更多的击键。
@sehe我非常了解寄存器,但是每次剪切/粘贴操作会增加4次击键,并且需要更多的深思熟虑。当您进行大量编辑时,这很快就会增加。
除了节省几个字节的内存之外,与任何其他寄存器相比,使用黑洞寄存器是否有优势?我会争辩说,如果你不读回任何寄存器,它都可以是黑洞寄存器。

D
Dorian

Vp:选择行,粘贴被拉出的内容


VP 也可以,这很方便,因为您可以在整个序列中按住 Shift。
非常好的技巧,尽管值得注意(可能)重要的警告:这会导致 yank 寄存器使用被覆盖的行的内容进行更新,因此它可能无法很好地处理某些任务 - 例如,如果你想覆盖同一条线路到多个目的地。
@underscore_d,如果您执行 V"0p,它会很好地播放,它从最后一个被拉出的寄存器中粘贴。
@timbaktu 你能解释一下 V"0p 的作用吗? V 进入视觉线模式,p 用于粘贴。什么是 " 和 0 ?谢谢
@theprogrammer " 用于寄存器,0 是 yank 寄存器。所以 "0 告诉 p 从 yank 寄存器中粘贴。这个寄存器与默认寄存器是分开的,默认寄存器是 Vp 将删除的(yank 填充默认寄存器和它自己的寄存器)。
i
icecrime

我会做什么:

aG Y xG 副总裁

您不必离开正常模式,但它确实拉线。但是,您可以使用 V"0p,它将始终将行拉到第 2 步。


@duddle:是的,Yyy 的同义词
步骤 1 和 2 可以使用 :ay [Eg :20y] 组合,然后是 Vp 应该可以解决问题。你不必去一条线来拉它。
如果您使用 ccCTRL+r0ESC 而不是 V"0p 覆盖其他行,则所有以下行都可以仅替换为 . (中继器)
我不明白什么是 aGa 将在光标后一个字符进入插入模式,而 G 将只插入一个大写 G 字母。
@vdegenne 我认为“a”只是代表行号。所以在普通模式下,36G 将是“转到第 36 行”。
E
Eugene Yarmash

这有一个额外的缺点,即第 X 行现在在默认寄存器中,如果我发现另一行应该用 A 替换,这很烦人。

要在不影响正常寄存器的情况下删除文本,可以使用黑洞寄存器 "_

"_dd

我向我的 .vimrc 添加了一些映射,以使 ddd 始终使用黑洞,并且 xxx 执行大多数编辑器所称的“剪切”(删除并保存到默认寄存器): noremap x d noremap xx dd noremap d "_d noremap dd "_dd
我对在 VIM 中重新映射东西持谨慎态度,因为这在其他计算机上或在 IDE 的 VIM 样式插件中可能并不容易。此外,如果您真的深入研究,VIM 的设计者往往会解决默认映射的问题。
R
RichardW

基于建议使用 VpVP 粘贴一行的答案——为了避免更改 yank 寄存器的内容,我发现最符合人体工程学的命令很简单:

VPY


这是使 yank 内容保持不变的最简单的解决方案。非常感谢!
n
naught101

yy j(移动到要替换的行),然后是 Vp(大写 v,然后是 p,将替换为被抽出的内容)


惊人的!确实很短,并且可以很容易地在可视模式下选择多行。它还保持粘贴缓冲区完好无损。当 dd 覆盖该缓冲区时,这很烦人......
@Aktau 这不会使缓冲区完好无损。
s
sehe

我会使用命令行(Ex)模式并执行以下两个命令

:XmA
:Ad

这只是将行 X 移动到 A 下方,然后删除 A 移动该行

例如

:7m3
:3d

能给我举个例子吗?当我按下例如 50Gm30G 时,Vim 转到第 50 行,然后到底部,就是这样。另外 :Ad 对 A=50 或 A=50G 没有任何作用
W
Wrzlprmft

移动到第一行的开头。 y, $ – 复制末尾没有换行符的行移动到目标行的开头。 V, p – 仅替换一个目标行 c, c, Ctrlr, 0, Esc – 用原始 yank 替换目标行 移动到下一个目标行的开头。 . – 重复 4.2 中发出的命令。

笔记:

4.1 是 y, $ 因为如果您执行 y, y 或 Y 您将复制换行符,而 Ctrlr, 0 实际上会在目标行下方添加换行符。

4.2 替换了 V p,它不适用于重复,因为从技术上讲,最后一个操作是删除,所以 .只会删除一行。

如果有人知道如何从 EX 模式(命令行)发出“用寄存器替换当前行”,我想听听您的意见(并想知道您在哪里找到了文档)。可能有一个可重复的 EX 命令,它比 4.2 更快和/或没有换行警告。


步骤 4.2 是这里的杀手,因为您现在可以像 4.3 一样使用 dot 命令重复整个过程——这就是 vim 的全部内容!
我不明白这个。 'AG' 将我的制造商放在行尾,进入插入模式并输入'G'。我没有得到什么?
@gustafbstrom 公平的批评 - 抱歉 A 应该代表行号,但我没有指出这一点。已编辑。
K
Kozmonaut

你也可以这样做:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)

不创建空格或行尾。

光标位于复制文本的开头。

相同的键可用于拉出/粘贴多行。

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)

B
Brian Rasmussen

这就是我要做的

移动 A、AG 行的开头(其中 A 显然是行号)

将行拉到某个寄存器,例如 a(没有新行)。键入“ay$

移动到插入线,XG

替代线,S

从寄存器 a 插入,Ctrl-Ra


N
Nathan Fellman

您可以将其与可视模式一起使用。

前往 A 行:AG

选择具有视觉模式的行:VESC

转到第 X 行:XG

进入该行的替代模式:S

粘贴您复制的行:shift+insert(或您映射的任何其他用于从剪贴板粘贴的行)。


啊。不知道 V 和 S。但是,您的步骤对我不起作用,因为我没有拉到我的操作系统剪贴板,这是我唯一可以在插入模式下访问的剪贴板。所以我必须先离开插入模式。
n
nkalvi

根据 cicld 最近的评论(谢谢!),我发现我没有完全理解原始问题。移动线是不合适的,但复制是(因为线被拉动了。)所以我将它修改为:

:1t20:20d_

复制第 20 行之后的第一行(:t 命令是 :copy 的别名)(将放在第 21 行) 删除第 20 行,将删除的行放入 'blackhole' 寄存器(_)(即不影响当前 yank缓冲)

正如最近评论中提到的,这不会影响当前光标位置。


N
Nafaa Boutefer

您可以在正常模式下使用此命令:

:AmX | Xd

m 命令用于m[ove],它将行号 A 移动到行号 X 之后,如果要复制而不是移动行,请使用 co[py]d 命令用于 d[elete]

您可以使用移动(使用 co 复制)一系列行

:start,end m X

B
Bharad

:ay(其中 a 是行号。例如:20y)。这会拉出一条线(双关语)。副总裁


n
nk3181544

我发现为此使用 Ex 命令更容易;前任。将第 9 行移至第 46 行:

 :46|9m.|-1d

这会将光标移动到第 46 行,将第 9 行移到当前行下方,然后删除上一行(因为移动的行是当前行)。

或使用标记,使用标记'a':

:46ma a|9m'a|'ad

EX 命令的美妙之处在于您可以在光标所在的任何位置运行它们(在正常模式下)。我更喜欢 :1m20|.+1d(将第 1 行移至第 20 行并删除下一行,即先前位于第 20 行的文本)。不过同样的想法!
R
Ron

我经常需要 Y 一行并在多个地方替换它,每个地方都有不同的值(这意味着我不能做正则表达式)。

Y 拉出所需的原始行

然后在你想替换的每一行上,VpzeroY


j
j5shi

我会简单地使用“黑洞”寄存器:

给定:

nnoremap "_dd

解决方案是:

< 镉 >yy


G
Gregory

如果您只想更改部分行,您可以这样做:

移动到要复制的文本部分的位置

y,$ - 从光标拉到 EndOfLine

移动到要替换的位置

v,$,p - 用寄存器的内容从光标替换到 EndOfLine