在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
的前del
和1,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
这个运动并不是最好的(我不是专家),但它可以像你想要的那样工作。 希望有一个更短的版本。
这是先决条件,所以这项技术运作良好:
abc
和def
中的示例中)具有相同的XOR长度