如何删除大块文本而不计算行数?


91

在vim中,我经常需要删除或拉大文本块。

我可以计算文本的行数,然后输入类似50dd删除50行的内容。

但这有点痛苦。如何删除此大块文本,不必事先知道要删除多少行?


4
你怎么知道终点在哪里?如果可以描述目的,则可以删除到这一点。如果您能形容move到最后。然后删除到末尾与移到末尾没有什么不同。
马丁·约克

@Loki,移至末尾通常只是使用下一页和箭头键,直到到达那里为止。它可以是第一行或第十行,也可以是第一个封闭括号。底线是,它变化很大。

2
还要检查以下答案:stackoverflow.com/a/16407391/164835
肯特

Answers:


111

转到块的起始行,然后键入ma(标记“ a”,尽管您当然可以使用不同的字母,甚至多个字母用于不同的标记,但前提是您可以将它直接记在脑海中,每个字母代表一个标记) 。

然后转到最后一行,并输入d'a(删除以标记“ a”)或y'a(拉动以标记“ a”)(a)

这将从当前行到已标记行(包括端)中的所有行删除/添加。

然后,您可以使用常规粘贴命令将其粘贴到其他位置,例如pP

它也与vi和兼容,vim以免您的环境没有幸免于后者。


(a)如果我不得不去别处寻找诸如复制粘贴要调用的函数的定义之类的东西,我也用它来保存我在文件中的位置。

我只是以相同的方式标记当前行ma,然后徘徊以查找所需的内容。

然后,一旦找到它并将其复制到寄存器中,我就输入'a回去标记“ a”,这是我预先保存的行,然后可以在其中粘贴。


9
还可以为此使用可视模式,对吗?
jmc 2015年

3
jmc 是一种方式,但是我不确定标准 vi是否具有可视模式。

5
自从大约一年前我从视觉选择转向标记和相对行号以来,我发现vi motion命令比视觉选择要快捷,高效。即使每次按下琴键后都比较容易,v我还是问自己是否真的需要它,还是有更好的运动方式?
Sukima,2015年

1
是的,以同样有趣的方式,@ Sukima,即使在GUI中,使用鼠标也越少,我的效率就会越高。如果我能继续使用键盘,我会发现自己会更快。

3
如果您要编辑的行确实很长,那么反引号版本也可能会派上用场(这是指行内的位置,而不是整行)。
msouth

65

在Vim中,使用视线模式

  1. 将光标放在文本/代码块的顶行以将其删除
  2. V(大写的“ V”:Shift+ v
  3. 将光标向下移动到文本/代码块的底部以将其删除
  4. d

对于删除大块文本,这比简单的可视模式更可取,因为您无需担心光标位于哪一列。


3
在步骤3中,您可以使用对象运动来更快地移动。例如可以}用来选择整个段落或)句子。还有更多内容,您可以在:h object-motions
mxlian

2
搜索子字符串/something<CR>也是一种非常有效的方法,可以到达选择块的末尾
mxlian 2015年

1
这是我的首选方法。但是,也可以不必重复按下j以向下移动光标(第3步),而可以键入行号,然后G选择直到该行。示例:V150Gd
Ranhiru Jude Cooray


39

您可以在知道其结构的情况下轻松删除大块文本。

如果是段落,请使用:(d{例如,您可以在段落数前添加前缀)

如果是括号内的代码块,请使用: d%

如果文本显示到文件末尾,请使用: dG

如果您知道它的结尾,请使用:d/并键入结尾文本,后跟Enter(您也可以使用正则表达式,因此可能性无穷)。

或者,使用可视模式(V)并使用移动键快速选择文本(例如通过{)并删除文本(d)。

或如Lie Ryan所建议,用于d/search-string/e从当前光标删除文本到搜索的字符串。

请参阅::help d以及:help motion更多信息。


2
d/search-string/e可以从当前光标删除到搜索字符串的末尾,包括搜索字符串本身,并c/search-query在删除后进入插入模式。使用d/with set incsearch是一个巧妙的组合,因为它可以交互式地确定您是否在正确的文本范围内进行操作,并帮助您知道何时停止键入搜索查询,以避免键入不必要的内容。
Lie Ryan

4
我还发现d使用a(外部)或i(内部)以及对象说明符非常有用。的对象,如w为单词,p段落,(b(...)[[...]{B{...}视觉运营商的文档
Shahbaz 2015年

22

您可以使用动作和/或文本对象。例如,您可以使用删除从光标到下一个空白行的所有内容d}。如果光标位于段落中,则可以使用dip或删除该段落dap。如果光标在HTML标记内,则可以使用dit或删除它dat

这些良好的助记“ d elete n面”和“ Ð elete 圆”(段/标签/括号)。


11

我通常会

:<start>,<end>d

它将删除提供的开始和结束行号之间的每一行(包括给定的行)。

请注意,startend都可以是绝对行号,样式或与另一个位置的偏移量。

另请参见doubleDown有关查看Vim 范围文档的评论,其中有一些有用的技巧。

例:

说您有以下文件:

1. The quick brown
2. fox jumps
3. over the
4. lazy dog.

然后,通过使用命令:2,3d:/fox/,/over/d:/quick/+1,/lazy/-1:+1,+2d如果您位于第一行或:-1,.d第三行,则最终得到:

1. The quick brown
4. lazy dog.

但这意味着您仍然需要数行吗?还是我误会了你的答案?
马丁·图尔诺伊

7
您不需要计算行数,但是您确实需要知道行号。
jmc 2015年

首先执行:set ruler,然后转到文本的顶部和底部以查找startend行号,然后执行:<start>,<end>d
roblogic 2015年

1
您也可以使用相对行号:+12,+24d
rpattabi

2
其实,你可以使用一对线号,一对图案,或混双的<start><end>这一点。供参考,请参阅:h [range]。因此,它实际上比您想象的要灵活得多。
doubleDown

5

如果您要处理的是定界的块(例如:代码或XML / HTML标记),则可以将光标定位在块的开头,并使用可视模式以及%快速选择整个代码块,然后点击d删除它们。


5
另外,您也可以使用dap删除一个段落,da(da{da[,删除括号,括号或方括号delimeted块。对于html,有dat,它删除标记,da'da"删除字符串。还有dipdi(,etc变体,它将删除定界符内的所有内容,但保留定界符不变。或者,您可以使用vap(resp vip)选择所有(resp内部)段落。(还有va(vi(。)此外,还有capcip(或ca(ci()要删除并进入插入模式(即“更改”)。并yap致谢
jmc 2015年

我认为他较早的注释中描述的某些绑定@jmc来自Tim Pope的Surround.vim插件。我建议安装这是一个很棒的插件,但这确实意味着这些绑定不是默认vim安装的一部分。
Haegin

5

除了所有其他好的建议,我还要添加d+ Shift+ L来删除从当前光标位置到屏幕上最后一个可见行的所有内容。重复执行该命令会使您相对较慢。


5

numbers.vim插件正是这个非常有用的。这是在每行之前加上行号的一种增强方法。就像'number'和一样'relativenumber',都扮演了一个角色!

它在安装后默认情况下set number处于启用状态,如果还没有,您还想添加到vimrc中,因为如果没有它,它的行为会很奇怪。

正常模式下,它类似于:set relativenumber

  3 call plug#begin('~/.vim/plugged')
  2 
  1 Plug 'myusuf3/numbers.vim'
7   set number█
  1 
  2 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
  3 Plug 'Yggdroot/indentLine'

它显示了相对的行号,光标所在的行除外,它显示了绝对行号(在这种情况下为7)。

如果我们随后切换到插入模式,它的行为就像number总是通过显示绝对行号进行设置一样:

  4 call plug#begin('~/.vim/plugged')
  5 
  6 Plug 'myusuf3/numbers.vim'
  7 set number█
  8   
  9 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
 10 Plug 'Yggdroot/indentLine'

还有更多选项和一些命令(请查看主页),但是默认设置适用于大多数人。


起初我以为这个答案有点离题,但是后来我安装了插件,不得不说这对我来说是改变游戏规则的人。我过去经常手动进行交换,而额外的心理步骤意味着我回避使用那些动作。谢谢!
Sukima 2015年

1
这听起来像一个InsertEnter / InsertLeave autocmd可以切换相对行号的功能。我想念什么吗?
2015年

我很晚才参加聚会,但是@Ben是正确的,这只是几个自动命令行。举例来说,在我的vimrc我set numberset relativenumber然后autocmd InsertEnter * :set norelativenumberautocmd InsertLeave * :set relativenumber
B层的

4

另一种方法是,如果您尝试删除为特定的模式,则只需键入即可d/delimEnter


2

您可以使用输入d加动作的常规步骤(如其他答案中所述)。EasyMotion插件提供了可以使用的新动作,可以快速轻松地解决您的问题。

假设您要从当前光标位置删除到屏幕上任何给定单词的末尾,则动作键将为<Leader><Leader>e(类似于正常e动作)。然后键入出现在相关单词末尾的突出显示的字母。还有一个直线运动,因此您可以使用删除当前行,直到相关的行<Leader><Leader>j

我的<Leader>密码设置为,。因此,完整的命令是d<Leader><Leader>e{突出显示的字母}。

来自:help easymotion

EasyMotion提供了一种在vim中使用某些动作的简单得多的方法。它采用<number>了的<number>w或<number>˚F {char}突出显示所有可能的选择,并允许您按一个键直接跳转到目标。

触发可用运动之一时,光标之前或之后的所有可见文本都将淡入淡出,并突出显示运动目标。

编辑:

EasyMotion的github存储库位于https://github.com/Lokaltog/vim-easymotion

对使用的EasyMotion人reddit的可能是一个有趣的阅读。


1

有一个简单的解决方案可以解决您的问题。

将光标放在要删除的文本块的开头,然后执行d50gg

这将从当前位置到文本的第50行删除所有行。

eq:如果光标在第46行,d50gg将删除4行。


1
我建议使用G而不是gg,因为它也可以在vi中使用,并且:set number对于查找您要转到的行的行号当然总是有用的。
2015年

这个问题的全部要点是您不知道要删除多少行。
200_success,2015年

200_success,您不必知道要用我发布的答案删除多少行。您所需要知道的就是“您想删除哪条线”
Geee

1

使用视觉模式加亮线。

  1. 将光标放在文本/代码块的顶行以将其删除
  2. Shift+v
  3. 将光标向下移动到文本/代码块的底部以将其删除
  4. d

我更喜欢这种方法来删除代码块,因为与简单地使用可视模式相比,它必须删除整行,在可视模式下,您必须将光标置于右列以删除所需的内容。


3
您基本上可以通过@ 200_success重复答案。
MartinSchröder'15

1

我不喜欢一直relativenumber这样,所以我将Vim配置为仅在处于可视模式时才启用它:

" Entering Visual mode
nnoremap <silent>     v :set relativenumber cursorcolumn<CR>v
nnoremap <silent> <C-q> :set relativenumber cursorcolumn<CR><C-q>
nnoremap <silent>    gv :set relativenumber cursorcolumn<CR>gv
nnoremap <silent>     V :set relativenumber<CR>V

" When finished
augroup ClearCursorColumnAndLine
    autocmd!
    autocmd CursorHold * set norelativenumber nocursorcolumn nocursorline
augroup END

这使您的任务变得容易:

V49jd

因为点击后V您可以看到目标线有多远。

从长远来看,这可能会令人讨厌(当启用/禁用relativenumber时,文本左右移动),但是到目前为止,我还是很喜欢的。


1
我觉得你用v<Esc>d50j
马丁·图尔诺伊

谢谢,我确实写错了。实际上,V如果我知道将要进行逐行操作,那么我将首先开始,然后我可以将其保留d到最后,以获得更大的信心。
joeytwiddle

我的回答似乎是一个穷人对number.vim插件的近似。;-)
joeytwiddle 2015年

1

与我合作的最佳方法是vi

  1. :set number 查看行号,直到我想删除的地方;

    +1289 idle 
    +1289 idle 
    +1290 # <- I want to delete until here
    +1291 if [[ ! -z "$SFIN" ]]
    
  2. 返回删除必须开始的行

  3. 在正常模式下从当前行使用删除 d1290G
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.