【问题标题】:Vim: Replacing a line with another one yanked beforeVim:用之前拉过的另一行替换一行
【发布时间】:2011-05-30 19:56:51
【问题描述】:

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

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 次击键,并且需要更多的深思熟虑。当您进行大量编辑时,这会很快加起来。
  • 除了节省几个字节的内存之外,与其他任何寄存器相比,使用黑洞寄存器是否有优势?我认为任何寄存器都可以是黑洞寄存器,如果你不读回它。

标签: vim


【解决方案1】:

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

【讨论】:

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

我会做什么:

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

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

【讨论】:

  • @duddle:是的,Yyy 的同义词
  • 第 1 步和第 2 步可以使用 :ay [例如:20y] 其次是副总裁应该做的伎俩。你不必去排队拉它。
  • 如果你用 ccCTRL+r0ESC 而不是 V"0p 覆盖其他行,那么后面的所有行都可以只替换为 . (中继器)
  • Yyy 的同义词,但我建议将其重新映射为y$ 以匹配DC
  • 查看下面 Jordan Morris stackoverflow.com/users/970673/jordan-morris 的答案 - 通过允许您多次重复该命令,真正充分利用了 vim 命令。
【解决方案3】:

这还有一个缺点 该行 X 现在是默认值 注册,如果我发现这很烦人 应该替换的另一行 与 A.

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

"_dd

【讨论】:

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

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

VPY

【讨论】:

  • 这是保持 yank 内容不变的最简单的解决方案。非常感谢!
【解决方案5】:
  1. yy
  2. j(移动到要替换的行),然后
  3. Vp(大写 v,然后是 p,将替换为抽出的内容)

【讨论】:

  • 太棒了!确实非常短,并且可以轻松地在可视模式下选择多行。它还保持粘贴缓冲区完好无损。当 dd 覆盖该缓冲区时,这很烦人......
  • @Aktau 这不会使缓冲区保持完整。
【解决方案6】:

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

:XmA
:Ad

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

例如

:7m3
:3d

【讨论】:

  • 你能举个例子吗?当我按下例如50Gm30G Vim 到第 50 行,然后到底部,就是这样。另外 :Ad 对 A=50 或 A=50G 没有任何作用
【解决方案7】:
  1. 移动到第一行的开头。

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

  3. 移动到目标行的开头。

    1. V, p – 只替换一个目标行

    2. ccCtrlr0Esc – 将目标行替换为原来的 yank

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

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

注意事项:

  • 4.1 是 y$ 因为如果你这样做 yy Y 您将复制换行符,而 Ctrlr0 实际上在目标行下方添加换行符。

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

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

【讨论】:

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

你也可以这样做:

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)

【讨论】:

    【解决方案9】:

    这就是我要做的事情

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

    【讨论】:

      【解决方案10】:

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

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

      【讨论】:

      • 啊。不知道 VS。但是,您的步骤对我不起作用,因为我没有拉到我的操作系统剪贴板,这是我唯一可以在插入模式下访问的剪贴板。所以我必须先离开插入模式。
      【解决方案11】:

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

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

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

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

      【讨论】:

        【解决方案12】:

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

        :AmX | Xd
        

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

        您可以使用

        移动(使用co 复制)一系列行
        :start,end m X
        

        【讨论】:

          【解决方案13】:
          1. :ay(其中 a 是行号。示例:20y)。这会拉出一条线(双关语)。
          2. 副总裁

          【讨论】:

            【解决方案14】:

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

             :46|9m.|-1d
            

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

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

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

            【讨论】:

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

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

            Y 拉出所需的原始行

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

            【讨论】:

              【解决方案16】:

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

              给定:

              nnoremap "_dd

              解决办法是:

              yy

              【讨论】:

                【解决方案17】:

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

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

                y,$ - 从光标拉到 EndOfLine

                移动到要替换的位置

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

                【讨论】:

                  猜你喜欢
                  • 2014-07-31
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-08-16
                  • 2013-01-25
                  • 1970-01-01
                  • 2017-08-14
                  • 1970-01-01
                  相关资源
                  最近更新 更多