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


112

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

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

我认为我不能有效地执行该任务。

我做的事:

  • 转到A行:AG
  • 复制行答:YY
  • 转到第X行:XG
  • 粘贴线A:P
  • 移至旧行:j
  • 删除旧行:dd

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

我的问题:

  • 我是否错过了内置的Vim命令来替换之前被拉动的行?
  • 如果没有,如何绑定我自己的命令,该命令将(或恢复)被拖拽的行保留在默认寄存器中?

2
这是我关于Vim编辑模型的最大问题。我很想知道一个解决方案。CUA编辑器区分剪切和删除,因此您只需剪切一些文本,然后就可以删除并粘贴所有想要的文本。使用Vim,您所做的任何删除都会破坏剪切的文本。与其他编辑器相比,您最终使用的击键次数要多得多。
Mud 2010年


@Mud了解:move黑洞寄存器(_)(或者实际上只是寄存器)
2012年

2
@sehe我非常了解寄存器,但是每个剪切/粘贴操作增加了4次击键,并且需要更多的预见。当您进行大量编辑时,这很快就会加起来。
2012年

除了节省一些字节的内存外,与其他任何寄存器相比,使用黑洞寄存器还有优势吗?我会争辩说,如果您不回读任何寄存器,那么它都可以是黑洞寄存器。
sleblanc

Answers:


91

我会怎么做:

  1. aG
  2. Y
  3. xG
  4. Vp

您不必离开普通模式,但是确实可以拉线。但是V"0p,您可以使用它将始终在步骤2中拉线。


11
@duddle:是的,Yyy
icecrime的

8
可以使用:ay [Eg:20y]将步骤1和2组合在一起,然后Vp应该可以解决问题。您不必去排队就可以拉它。
巴拉德

2
如果您用ccCTRL + r0ESC而不是V“ 0p覆盖其他行,则随后的所有行都可以替换为。(转发器)
Jordan Morris

Y是的同义词yy,但我建议重新映射y$以匹配DC
mgold 2013年

在下面查看Jordan Jordan Morris stackoverflow.com/users/970673/jordan-morris的答案-允许您多次重复使用该命令,从而真正充分利用了vim命令。
JESii 2014年

105

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


3
VP效果也一样,这很方便,因为您可以在整个序列中保持Shift不变。
乔治·希利亚德

23
这是一个非常不错的技巧,尽管值得注意(可能)有一个重要警告:这会导致yank寄存器被覆盖的行的内容更新,因此它在某些任务上可能效果不佳-例如,如果您想覆盖同一行到多个目的地。
underscore_d

8
@underscore_d,如果您这样做会很好地播放V"0p,它将粘贴到最后一个被寄出的寄存器中。
timblaktu

@timblaktu你能解释一下V"0p吗?V进入可视行线模式,p进行粘贴。“和0代表什么?”谢谢
程序员

43

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

要删除文本而不影响普通寄存器,可以使用黑洞寄存器"_

"_dd

10
我加了一些映射到我的.vimrc使ddd经常使用的黑洞,并xxx执行大多数编辑们称之为“切”(删除并保存到默认的寄存器):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSOP

2
我很警惕在VIM中重新映射内容,因为在其他计算机或IDE的VIM样式的插件中这可能不容易。而且,如果您真的喜欢的话,VIM的设计师也倾向于解决默认映射的问题。
约旦·莫里斯

15

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

VPY


这是最简单的解决方案,可以保持相同的洋基含量。非常感谢!
heylookltsme​​ '19

14
  1. y
  2. j(移至要替换的行),然后
  3. Vp(大写的v,然后是p,将替换为被选中的内容)

太棒了!确实很短,可以很容易地在可视模式下选择多行。它还可以使粘贴缓冲区保持完整。当dd覆盖该缓冲区时,这很烦人……
Aktau

@Aktau,这不会使缓冲区完整。
约旦·莫里斯

9

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

:XmA
:Ad

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

例如

:7m3
:3d

能给我举个例子吗?当我按下例如50Gm30G时,Vim转到第50行,然后到底部,仅此而已。另外:对于A = 50或A = 50G,广告不执行任何操作
脆脆的

7
  1. 移至第一行的开头。

  2. y$–复制行末没有换行符

  3. 移至目标行的开头。

    1. Vp–仅替换一条目标线

    2. ccCtrlr0Esc-与原抽出更换目标线

  4. 移至下一个目标行的开头。

  5. . –重复在4.2处发出的命令。

笔记:

  • 4.1 y$因为如果你这样做yy或者Y你会复制断行,并且Ctrlr,  0实际上增加了你的目标线以下的换行符。

  • 4.2 replaces V p不能与repeat一起使用,因为从技术上讲最后一个动作是delete,所以.只删除一行即可。

  • 如果有人知道如何通过EX模式(命令行)发出“用寄存器替换当前行”的信息,我希望收到您的来信(并知道您在哪里找到了文档)。可能存在比4.2更快的可重复EX命令,并且/或者没有换行警告。


1
步骤4.2是这里的杀手,,因为您现在可以像4.3一样使用dot命令重复整个过程-这就是vim的全部意义所在!
JESii 2014年

1
我不明白 'AG'将我的制造商置于行尾,进入插入模式并输入'G'。我不明白是什么?
gustafbstrom

@gustafbstrom公平的批评-很抱歉A应该代表行号,但我没有指出。编辑。
乔丹·莫里斯

5

这就是我要做的

  • 移动A行的开头, AG(其中A显然是行号)
  • 将行拉到某个寄存器,例如a(不带新行)。类型"ay$
  • 移动到插入行, XG
  • 替代线, S
  • 从寄存器a插入 Ctrl-Ra

4

您可以在可视模式下使用它。

  • 转到A行: AG
  • 用可视模式选择行: VESC
  • 转到X行: XG
  • 输入该行的替代模式: S
  • 粘贴您复制的行:shift+ insert(或其他任何要从剪贴板粘贴的映射)。

啊。不知道V小号。但是,您的步骤对我不起作用,因为我不喜欢我的OS剪贴板,这是我只能在插入模式下访问的剪贴板。因此,我必须先离开插入模式。
脆皮

3

您也可以这样做:

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)

2

您可以在普通模式下使用以下命令:

:AmX | Xd

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

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

:start,end m X

2

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

:1t20:20d_
  1. 在第20行之后复制第一行(:t命令是的别名:copy)(将其放置在第21行)

  2. 删除第20行,将删除的行放入“黑洞”寄存器(_)(即不影响当前的yank缓冲区)

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


1
  1. :ay(其中a是行号。示例:20y)。这拉了一条线(双关语意)。
  2. 副总裁

1

我发现使用Ex命令更容易。例如 将第9行移至46:

 :46|9m.|-1d

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

或使用标记,使用标记“ a”:

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

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

1

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

Y 拉动所需的原始线

然后在您要替换的每一行上, VpzeroY


0

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

给出:

nnoremap <Cd>“ _dd

解决方案是:

<镉> yy

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.