如何在vim中删除当前行下面的行?

108

是否有一种命令可以删除当前行下方的一行或多行? 目前我是这样做的: jdd,然后用.重复需要的次数。 有没有一种命令可以将所有这些命令结合起来呢?

更新:我想有这样一个命令的原因是,我不喜欢离开当前位置,但又希望能够删除下方的行。


我认为@Peter Rincker的回答应该被标记为答案。 - gixxer
完成了@gixxer,谢谢你的提醒。 - Valentin V
9个回答

189

删除ex命令将起作用。

:+,$d

这将删除当前行加1直到结尾($)的所有行。

要删除接下来的两行,可以使用以下范围:+1,+2或更简单的+,+2

:+,+2d

正如@ib提到的那样,:delete:d命令将把光标移动到删除文本旁边行的开头。(即使设置了nostartofline)。为了解决这个问题,我们可以输入`` normal模式命令。``会跳回到上次跳转之前的确切位置,在这种情况下是:d命令。我们的命令现在是:

:+,+2denter``

或者作为一个ex命令

:+,+2d|norm! ``
为了使这更加容易,我们将其全部包装在一个命令中:
command! -count=1 -register D :+,+<count>d <reg><bar>norm! ``

现在要删除接下来的三行:

:3D

此命令还可以像:delete:yank一样,使用{reg}参数。因此,将下面的4行删除到寄存器a中,命令为:

:4D a

更多信息请参考

:h :d
:h :command
:h :command-register
:h :command-count
:h ``

3
请注意,这是一种相当简单的解决方案,可以轻松实现,并且可以应用于其他命令(例如,: +1,+5s!a!b!g 将在光标后的4行中将a替换为b)。有关更多示例,请参见 :help command-ranges。 - David Winslow
这个直接的解决方案很好,如果它不移动光标的话就更好了。至少,命令应该看起来像 :+,$d|norm!\``。顺便说一下,正如问题中所述,问题的提出者想要删除当前行下面的几行,而不一定是一直删到文件结尾。 - ib.
@ib:通过更详细的区间说明,可能会改善答案。也许可以用 set sol?如何使用 ``` 标记? - Peter Rincker
@Peter:很可能是这样。顺便说一下,仅关闭sol并不能解决问题:当使用:+,+3d删除三行时,光标会移动到已删除行的下一行。 - ib.
@ib:我已经将您的建议融入到我的答案中。感谢您的反馈。 - Peter Rincker
:.,$d 包括当前行(而不是从下一行开始)。 - Trevor Boyd Smith

124

dG 应该可以使用。
这意味着从当前光标删除所有行,直到文件结尾。


这是最好的一个! - countach

33

这将删除当前行以下的所有行:

jdG

不幸的是,这将在删除完成后将光标移动到当前行的开头。


2
并且还会删除缓冲区之后的每一行。 - ib.
1
我误读了原问题,很抱歉。我以为楼主想要删除当前行以下的所有行。我修改了我的帖子。 - ClosedID

8

简单来说,您可以使用xxdd命令来完成。大多数情况下,我知道(至少有一个想法)我正在编辑的脚本的大小。因此,以下命令通常已经足够:

  • 99dd
  • 999dd 以删除从光标位置开始的999行。
  • 9999dd
  • 99999dd 用于非常长的脚本;)

4
其他解决方案很有用,但是我觉得使用宏可能更简单:
qq (开始录制)
jddk (向下移动,删除行,然后向上移动——也就是你想要做的事情)
q (停止录制)
现在,您可以执行@q来执行此操作,并将光标保持在当前位置。 您还可以执行类似于5 @ q的操作,以删除光标下面的5行。
最后,如果您需要重复执行该操作多次,只需在第一次运行@q之后键入@@即可(这会重复最后使用的宏-在此例中为q)。

2

这是一个适合使用标记的任务!

尝试maj20dd`a

ma设置文件特定的标记'a',j20dd执行您想要的删除操作(在本例中为20行),`a将您恢复到标记的位置(行和列)。

显然,此模式可以扩展以在返回标记之前执行任何您想要的操作。如果使用mA(或任何其他大写字母),则标记实际上将在文件之间唯一,因此您甚至可以在返回之前编辑其他地方。如果您经常使用它,可以像上面建议的那样将其制作为宏。


1
你可以输入要删除的行数:j 20 dd k

最后的 k 命令将光标移动到初始行之上。此外,由于 dd 命令,光标列位置将会丢失。 - ib.
@ib:在我的测试中并不是这样的。你真的试过吗?请注意最初的 j - Paul Ruane
很抱歉,我的第一点是错误的(当我尝试该命令时,我没有注意到我指定的计数(在您的示例中为“20”)大于直到缓冲区末尾的行数)。但第二个问题仍然存在:在执行“dd”命令后,光标的列位置会改变(我相信是移到了删除行下一行的第一个非空字符处)。 - ib.
@ib:是的,我同意列的位置会改变。 - Paul Ruane
请对您的答案进行微不足道的编辑,这样我就可以点赞了。毕竟我认为您的回答并不应该被负面评价。 - ib.
这些命令确实会将光标返回到原始行,但不会返回到原始位置。谢谢你的回答。 - Valentin V

0

你也可以使用:Shift + VShift + GShift + X


-2

只是为了好玩,您可以定义一个小函数,它可以执行您所描述的操作:删除当前行下面的下一个n行,并恢复初始光标位置。

function! DeleteNextLines(n, reg)
    let l = line('.')
    let m = min([a:n, line('$')-l])
    if m > 0
        let c = col('.')
        exe '+,+'.m 'd' a:reg
        call cursor(l, c)
    endif
endfunction

此外,您可以定义一个接受要删除的行数(如果省略,则为一行)和作为可选参数使用的寄存器名称的命令(就像:delete命令一样)。
:command! -range=1 -register -bar D call DeleteNextLines(<count>, <q-reg>)

此外,如果有必要,您可以定义一个映射来触发上述:D命令。

1:let mapleader = "," 2:nmap <leader>d :D<CR> - Kevin Lee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接