如何在vi / Vim中的多行选择的开头插入文本


423

Vim中,如何在选择的每一行的开头插入字符?

例如,//假设我的语言的注释系统不允许类似的块注释,我想在每行的开头添加注释来注释掉一段代码/* */。我该怎么做?

Answers:


748
  • Esc进入“命令模式”
  • 使用Ctrl+ V进入可视块模式
  • 移动Up/ Down选择要注释的行中的文本列。
  • 然后按Shift+ i,然后输入要插入的文本。
  • 然后点击Esc,等待1秒钟,插入的文本将出现在每一行上。

有关更多信息和阅读,请在Vim Tips Wiki中查看“ 多行插入文本 ”。


6
唯一的遗憾是它在GVIM中似乎覆盖了Ctrl + V。
乔丹·帕默

14
不适合我(在Linux上)不是
pixelbeat

23
您可以使用Ctrl-Q代替gVim(如:help Ctrl-V所述),但是您需要使用hjkl在此模式下导航,而不是箭头键
Gareth,

9
如果在Windows gvim中覆盖了ctrl-v,则应编辑全局vimrc以停止包含mswin.vim。
graywh

18
知道为什么在按esc键后它什么都不做吗?我等待着像10秒,事情发生不到一百行-没关系,我推Shift + vCTRL + v。@ vkaul11也许同样的事情,你做了什么洛尔
Tek公司

186

这将每行的开头替换为“ //”:

:%s!^!//!

这将用“ //” 替换每个选定行的开头(使用可视模式进行选择):

:'<,'>s!^!//!

注意的是gv(正常模式)恢复上次视觉选择,这个就派上用场了,不时。


3
谢谢!完全有意义。并删除文本如下:'<,'> s!^ // !!
乔丹·帕默

4
以上答案中的感叹号是什么意思?(:%s!^!//!)
Henrik K

19
@HKK,通常使用正斜杠字符/作为搜索和替换命令的分隔符。在这种情况下,我们将插入正斜杠作为搜索和替换的一部分,因此我们使用替代的分隔符,即感叹号!
网络僧侣

+1在VsVim中起作用,而(Ctrl + V)(Shiift + I)Esc不起作用。
塞斯·里诺

4
+1,不知道您可以使用其他东西作为正则表达式定界符(在这里我一直在使用/,必须逃脱//in :s/^/\/\/而不是写作:s!^!//
Hashbrown

83

搜索和替换的一般模式是:

:s/search/replace/

将当前行的第一次出现的“搜索”替换为“替换”

:s/search/replace/g

将当前行中所有出现的“搜索”替换为“替换”,“ g”是“全局”的缩写

此命令仅将当前行的每次出现的“搜索”替换为“替换”。%用于搜索整个文件。要以交互方式确认每个替换,请在后面附加一个“ c”以进行确认:

:%s/search/replace/c

交互式确认将整个文件的“搜索”替换为“替换”

您可以使用行号范围来代替%字符(请注意,'^'字符是行首的特殊搜索字符)

:14,20s/^/#/

在第14-20行的开头插入“#”字符

如果要使用其他注释字符(例如//),请更改命令定界符:

:14,20s!^!//!

在第14-20行的开头插入“ //”字符序列

或者,您总是可以转义//字符,例如:

:14,20s/^/\/\//

在第14-20行的开头插入“ //”字符序列

如果在编辑器中看不到行号,只需键入以下内容

:set nu

要删除开头的#:而不是:14,20s /#/ ^ /,则应使用:14,20s /#//
cn1h 2012年

1
@ cn1h我认为这也将替换#该行中的其他内容。您应该^#改用。
ankush981

感谢您解释基础知识。很高兴知道为什么会发生什么。
didierCH

38

对于新来者来说,另一种可能更容易的方法是:

 some█
 code
 here

将光标放在第一行,例如

gg

并输入以下内容进入插入模式并添加文本:

I / / Space

 // █some
 code
 here

Esc返回命令模式并使用有向图:

j . j .

 // some
 // code
 //█here

j是向下移动一行的运动命令,并.重复您上次执行的编辑命令。


3
那真的很简单:)。如果您遇到麻烦,可能是因为您输入的是横线(带有\的其他符号)|而不是大写字母I。我以为是一|开始。
cokedude 2014年

1
如果我做“ 5”。它从同一行删除5个字符。如何使其每行一次删除5个字符?
Rahul Prasad

1
@RahulPrasad假设您有25行,然后从第一行的开头开始,将5xj记录到一个寄存器中,并播放该寄存器24次,例如:qa5xjq25 @ a但是,如果您将其发布为实际问题会更好如果它还不存在……
ninegrid '16

26

还有另一种方式:

  • 移至行首
  • 进入可视块模式(CTRL- v
  • 选择所需的行(使用j/ 向上/向下移动k,或使用[line]跳至一行G
  • I(这是大写字母i)
  • 输入注释字符
  • ESC

20

这会#在每一行的开头添加:

:%s/^/#/

人们将不再抱怨您缺少适当的注释脚本。


2
如果您只想在选定的(或几条)线路上添加#怎么办
Rahul Prasad

15

如果您想对此一见钟情,请将其放入.vimrc中:

vmap \c :s!^!//!<CR>
vmap \u :s!^//!!<CR>

然后,只要在可视化模式,你可以打\cç omment块,并\uü ncomment它。当然,您可以将这些快捷键更改为任何形式。


由于它引入了一些新内容而被赞扬vmap
ankush981

11

另一种方式:

:'<,'>g/^/norm I//

/^/只是匹配每行的虚拟模式。 norm使您可以运行随后的普通模式命令。 I//表示在将光标跳到该行的开头时进入插入模式,然后插入以下文本(两个斜杠)。

:g 对于在多行上执行复杂的操作通常很方便,您可能需要在多个模式之间跳转,删除或添加行,在光标周围移动,运行一堆宏等。并且您可以告诉它仅在以下行上运行:匹配模式。


1
实际上:g命令不是必需的。这将做到::'<,'>规范I //
Cyber​​ Oliveira

1
和:s在这种情况下也更好。
graywh

这是最有用的答案。
2016年

3

对于注释代码块,我喜欢NERD Commenter插件。

选择一些文本:

Shift-V
...select the lines of text you want to comment....

评论:

,cc

取消注释:

,cu

或者只是切换行或块的注释状态:

,c<space>

2

我可以推荐EnhCommentify插件。

例如。将此放入您的vimrc:

let maplocalleader=','
vmap <silent> <LocalLeader>c <Plug>VisualTraditional
nmap <silent> <LocalLeader>c <Plug>Traditional
let g:EnhCommentifyBindInInsert = 'No'
let g:EnhCommentifyMultiPartBlocks = 'Yes'
let g:EnhCommentifyPretty = 'Yes'
let g:EnhCommentifyRespectIndent = 'Yes'
let g:EnhCommentifyUseBlockIndent = 'Yes'

然后,您可以使用',c'注释/取消注释(选定的)行



1

将要评论的区域标记为可视块(<C-V

并做 c#<ESC>p

  1. c挂在“#”上
  2. 放回去

如果您经常这样做,请\q在.vimrc中定义一个快捷方式(例如)

:vmap \q c#<ESC>p

1

如果某人的多行选择实际上是一个段落,则无需手动选择行。vim可以为您做到这一点:

  1. vip:选择并标记整个段落
  2. shift-i:在行首插入文本
  3. escape:保留插入模式/进入普通模式[仍选择行首]
  4. escape:取消选择行首

0

在每行的开头插入“ ABC”:

1)进入命令模式

2):%规范I ABC


这会将文本添加到该行中第一个非空格字符的左侧。
金斯利
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.