在Vim中合并多行(两个块)

我想在Vim中合并两行代码块,即采用第n..m行,并将它们附加到a..b行。 如果你更喜欢伪代码解释: [a[i] + b[i] for i in min(len(a), len(b))]

例:

abc
def
...

123
45
...

应该成为

abc123
def45

有没有一种很好的方式来做到这一点,而无需手动复制和粘贴?


你当然可以用一个复制/粘贴(使用块模式选择)来完成所有这些,但我猜这不是你想要的。

如果你想用Ex命令来做到这一点

:5,8del | let l=split(@") | 1,4s/$/=remove(l,0)/

将会转变

work it 
make it 
do it 
makes us 
harder
better
faster
stronger
~

work it harder
make it better
do it faster
makes us stronger
~

更新:与这许多upvotes一个答案值得更彻底的解释。

在Vim中,你可以使用管道字符( | )来链接多个Ex命令,所以上面的内容相当于

:5,8del
:let l=split(@")
:1,4s/$/=remove(l,0)/

许多Ex命令接受一个范围内的行作为前缀参数的-在上述情况下的5,8的前del1,4前的s///指定哪些线的命令进行操作。

del删除给定的行。 它可以采用一个寄存器参数,但是当没有给出时,它会将行转移到未命名的寄存器@" ,就像正常模式下的删除一样let l=split(@")然后将删除的行分割成列表,使用默认的分隔符:空格。 要在删除的行中有空白的输入正确工作,如:

more than 
hour 
our 
never 
ever
after
work is
over
~

我们需要指定一个不同的分隔符,以防止“work is”被分成两个列表元素: let l=split(@","n")

最后,在替换s/$/=remove(l,0)/ ,我们用表达式remove(l,0)的值替换每行的结尾( $ remove(l,0)remove(l,0)改变列表l ,删除并返回它的第一个元素。 这让我们可以按照我们阅读的顺序来替换已删除的行。 我们可以用remove(l,-1)代替相反顺序的删除行。


通过结合使用:global:move:join命令,可以获得解决问题的优雅和简洁的Ex命令。 假设第一行块从缓冲区的第一行开始,并且光标位于第二块第一行之前的行上,该命令如下所示。

:1,g/^/''+m.|-j!

有关所使用技术的详细说明,请参阅我给出的“Vim paste -d”行为开箱即用的问题的答案?“。


要连接线路块,您必须执行以下步骤:

  • 去第三行: jj
  • 进入视觉模块模式: CTRL-v
  • 将光标固定到行的末尾(对于不同长度的行很重要): $
  • 转到最后: CTRL-END
  • 切块: x
  • 转到第一行的末尾: kk$
  • 粘贴块: p
  • 这个运动并不是最好的(我不是专家),但它可以像你想要的那样工作。 希望有一个更短的版本。

    这是先决条件,所以这项技术运作良好:

  • 起始块的所有行(在问题abcdef中的示例中)具有相同的XOR长度
  • 起始块的第一行是最长的,并且你不关心其间的额外空间) 异或
  • 起始块的第一行不是最长的,并且您有额外的空间。
  • 链接地址: http://www.djcxy.com/p/22605.html

    上一篇: Merge multiple lines (two blocks) in Vim

    下一篇: Convert DOS line endings to Linux line endings in vim