【问题标题】:Vim yanking range of linesVim 拉取行范围
【发布时间】:2011-01-02 15:23:04
【问题描述】:

我是一名 C# 开发人员,最近决定扩展我对可用工具的了解。我决定学习的第一个工具是 Vi/Vim。到目前为止一切进展顺利,但有几个问题我似乎无法找到答案:

  1. 假设我想拉出一系列行。我知道有很多方法可以这样做,但我想按行号来做。我认为它类似于替代命令的工作方式,例如81,91y。有没有办法做到这一点?

  2. 我对正常模式下的g 命令有点困惑。它似乎做了很多事情,我无法真正确定 g 命令的核心是什么。我对它是运动命令还是其他命令通过正常模式运行的一种“全部捕获”感到困惑。有人可以解释一下吗,或者给我指出一个可以很好地解释g 命令的参考资料?

【问题讨论】:

  • 你知道 vim(1) 中的命令 ":help" 吗?
  • 是的,但我无法在所有参考文献中找到它。原来我在想我会在正常模式下做,但是 hometoast 展示了如何从命令模式下做。对于 g 命令,我只是发现帮助并没有像我对其他命令所期望的那样将所有内容联系在一起。
  • 顺便说一句,我可能想为每个问题发一个帖子。
  • 我以后会这样做的。我更关心第一个问题,我只是在输入第一个问题时想到了另一个问题。

标签: vim editor range vi yank


【解决方案1】:

从第 81 行拉到第 91 行:

方法一:81gg11yy

不错,但您必须做一点数学运算才能找出要拉出的行数

方法 2:81gg 然后shift+v 然后91gg 然后y

在我看来最好,因为这是直截了当的,你只需要知道显而易见的事情,即你想从哪个行号拉到哪个行号

【讨论】:

    【解决方案2】:

    作为 Vi/Vim 的老用户,我倾向于使用“标记”代替行号(或“行标记”)。它的工作原理是这样的:m 是“标记”字符;然后使用任何字母来识别/命名标记。要返回标记,请在命名标记前加上单引号 ('a),这些标记可用作范围。例子:

    File:
        <line 1>
        <line 2>
        <line 3>
        <line 4>
        <line 5>
    

    在命令模式下,将光标移动到第 2 行,输入ma。滚动到第 4 行,输入mb。 要从标记 a 拉到标记 b,请键入:

        :'a,'byank
    

    要从标记 a 删除到标记 b,请键入:

        :'a,'bdel
    

    从标记 a 搜索标记 b 并将 'ine' 替换为 'ink':

        :'a,'bs/ine/ink/g
    

    通过标记b复制标记a并粘贴到当前位置下方(“点”始终引用光标当前所在的行):

        :'a,'bco . 
    

    在标记 a 到标记 b 之间移动代码行,向右移动一个选项卡(使用相反的 V 形,&lt;,向左移动):

        :'a,'b> 
    

    在命令模式下,您只需键入 'a 即可移回标记,以移回标记为 a 的行。输入 '' 会让你回到之前的位置(不幸的是只记得之前的位置,而不是两个回来)。

    您可以在不知道行号的情况下拉取命名缓冲区、复制、删除行、搜索和替换部分代码等。

    【讨论】:

    【解决方案3】:

    除了:91,96y a 将(y)第 91 到 96 行拉入寄存器 a(用"ap 粘贴)之外,拉出的行可以附加到寄存器与:

    :91,96y A
    

    A 寄存器的大写导致对寄存器a 进行追加操作,而不是覆盖。寄存器的大写总是这样工作的,例如:let @A=';' 附加一个; 来注册a

    使用加号 (+) 或减号 (-) 引用相对于当前光标位置的行:

    :-10,+10y b
    

    即它会在当前光标位置周围 yank(y) 21 行并将它们放入寄存器 b

    没有输入实际上也代表当前光标位置,这意味着:

    :-5,y a
    

    将文本从上面 5 行拉到当前光标位置到命名缓冲区a,并且:

    :,+5y a
    

    会将当前光标位置之后的 5 行拉入缓冲区 a

    注意:如果缓冲区a 中有一个宏,它只是被之前的 yank 覆盖,因为 yank 寄存器和宏寄存器实际上是一回事。这就是为什么,巧合的是,您可以粘贴一个宏,对其进行编辑,然后将其拉回到它的寄存器中。我个人使用左手到达的字母表示 yanks,而右手到达的字母表示宏。

    移动文本块,如下所示:

    :+10,+13m.
    

    这意味着将位于当前光标前 10 行的四行移动到当前行的下方。

    附录

    我之前混淆了 :91,95ya a 中的 yaya{motion} 的同义词,其中的动作由 91,95 提供。这是不正确的,ya 中的“a”是完全没有必要的。在我的辩护中,我的help yank 并没有传达ya 可能是yank 的别名。

    【讨论】:

    • :ya:yank 的缩写,所以我不确定我对 yanks all lines 的感觉如何。但是很好地浓缩了一些零散的信息
    • 我也是这么想的,直到我看了:help yankyank 没有别名 ya。不过你是对的,a 并不代表“全部”,它在技术上代表“a”。不过,我还是更喜欢说“全部”,因为这对我来说更有意义。
    • :[range]y[ank] [x] Yank [range] lines [into register x] y[ank] 中的方括号表示[ank] 是可选的。 :y:ya:yan:yank 的隐式别名
    • 我已更正:) a 不是必需的。将编辑答案以反映。
    • 您的附录很好,但我指的是您的第一行,您使用 ex 命令 :ya 而不是普通命令 y
    【解决方案4】:

    最好的解决方案是按 v 进入“可视模式”。选择行后,按 y 复制它们。然后按 p 粘贴复制的行。

    【讨论】:

    • 不同意,但只有 bc 视觉模式有时会这么慢。
    • 如果您想将一系列行复制到其他运动命令无法获得的寄存器中,这实际上非常有用。选择后使用“ay”或“like”。
    【解决方案5】:

    g 自己不做任何事情。它是几个元命令中的一个,其中包含一堆排序无关的命令。

    z 是另一个类似的命令。

    【讨论】:

    • 谢谢。我现在明白它只是用于不同的目的。当我尝试学习这些工具时,我尝试将命令与我可以抽象的东西联系起来,以便我记住如何正确使用它。看起来 g 命令只是您需要记住才能正确使用的内容之一。
    【解决方案6】:

    G 命令转到某个行号,如果它伴随着一个计数值。 81G 让你进入第 81 行。

    y 命令可以与运动组合,例如G。因此,要将所有内容拉到第 91 行,您可以使用y91G

    你们一起得到:

    81Gy91G
    

    转到第 81 行,然后在转到第 91 行时猛拉。

    【讨论】:

    • 我希望我能不止一次地对此表示赞同。帮助我的是使用它来拉到一个寄存器(在我的例子中,寄存器 + 即剪贴板):81G"+y91G
    • @mgarey 有没有办法使用行范围语法直接拉入寄存器? 81,91y 并以某种方式针对寄存器?
    • @diplosaurus 可能,但我不知道。这听起来像是你可以在 vi.stackexchange.com 上问的一个问题,如果它不存在或不存在于 SO 上。我会感兴趣的。我不是 Vim 专家。
    • @mgarey 不得不通过谷歌搜索获得创意,但我在这里找到了它:stackoverflow.com/questions/16225366/…:81,91y +
    • @diplosaurus :81,91y + 不起作用。它适用于其他寄存器,例如:81,91y a,但似乎不喜欢+ 寄存器。这肯定对其他人有用吗?
    【解决方案7】:

    您还可以使用 't' 将当前行复制到当前光标位置。

    :81,91t.<enter>
    

    这会将第 81-91 行粘贴到光标所在行的下方。

    我是从http://vimcasts.org 那里学到的,这是一个关于 VIM 的优秀资源。

    【讨论】:

    • 这里的t. 是什么意思?
    • 据我了解t可以认为是till或to,.是当前行的地址。
    • @CivFan 它是:copy的同义词
    【解决方案8】:

    我也喜欢使用 vim 的相对行号选项,这意味着我可以直接输入:

    :-10,-7ya a
    

    将文本拉入命名缓冲区a。

    注意指定 A 会将您正在提取的内容附加到缓冲区 a 的当前内容中。

    别忘了你也可以使用类似的命令复制文本块和移动文本块:

    :-10,-7co .
    

    表示将上面10行的四行文本复制到当前行的下面,并且

    :-10,-7mo .
    

    表示将当前行上方10行的四行文本移动到下方。

    【讨论】:

      【解决方案9】:

      81-91 行

      :81,91y<enter>
      

      如果您的手指不喜欢找到 :, 键,这也可以(转到第 81 行,拉出 11 行)

      81gg11yy 
      

      我唯一使用g5gg。去5号线。 22gg:第 22 行。正如jimbo所说,它实际上只是其他一些命令的修饰符。

      为了完整起见,(http://vim.wikia.com/wiki/Power_of_g) 解释了很多 g 在命令模式下的工作原理。

      【讨论】:

      • 使用大写字母也提供了变化:gg 将转到第一行,而 G 将转到最后一行。此外,5G 转到第 5 行。标记也可以用来代替行号(适用于宏),即::'a,52y
      • 如果你不怕 Shift 键,81G11Y 会更“短”。
      • 普通模式方法的缺点是你失去了你的“位置”;你可以想象mx之前和'x之后但是命令模式版本变得更加简洁。嗯......我刚写完这篇文章,我就看到了@Asta 的答案。
      • @WilliamRoss 这实际上将行放在缓冲区中以供 vim 使用,不一定在系统剪贴板中,您可以使用 CTRL+V 粘贴到记事本中。查看相关问题:How to copy/paste text from vi to different applications
      • 这让我很开心,因为我寻找第一个解决方案的全部原因是避免在脑海中计算行数或做减法。
      【解决方案10】:

      Vim 的 :help indexg 描述为:

      |g|             g{char}            extended commands, see |g| below
      

      向下滚动(或:help g)查看列表。

      【讨论】:

      • 我熟悉 :help 但我不熟悉 :help(命令)。这在将来会非常有用。谢谢你,先生。
      猜你喜欢
      • 2023-04-02
      • 2022-11-14
      • 2010-09-20
      • 1970-01-01
      • 2013-12-09
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2012-03-21
      相关资源
      最近更新 更多