在Vim中评论/取消注释的快速方法是什么?

我有一个在vi中打开的Ruby代码文件,有几行注释掉了#

 class Search < ActiveRecord::Migration def self.up # create_table :searches do |t| # t.integer :user_id # t.string :name # t.string :all_of # t.string :any_of # t.string :none_of # t.string :exact_phrase # # t.timestamps # end end def self.down # drop_table :searches end end 

假设我想取消注释第一个def ... end部分中的所有行。 Vim中有效的方法是什么?

总的来说,我正在寻找一种简单stream畅的方式来评论和取消注释。 在这里,我正在处理Ruby代码,但它可能是JavaScript(/)或Haml( -# )。

我使用NERD Commenter脚本 。 它可以让您轻松评论,取消注释或切换代码中的注释。

对于那些我使用大部分时间块select的任务 。

将光标放在第一个#字符上,按Ctrl + V (或者Ctrl + Q代替gVim),直到最后一个注释行并按下x ,这将垂直删除所有#字符。

评论一块文字几乎是一样的:

  1. 首先,转到您要评论的第一行,按Ctrl V。 这将使编辑器处于VISUAL BLOCK模式。
  2. 然后使用箭头键并select直到最后一行
  3. 现在按下Shift I ,它将把编辑器置于INSERT模式,然后按 。 这将添加一个哈希到第一行。
  4. 然后按Esc (给它一秒),它会在所有其他选定的行上插入一个#字符。

对于默认带有debian / ubuntu的精简版vim,请在第三步中键入: s/^/#

在vim中注释块:

  • Esc (离开编辑或其他模式)
  • 点击ctrl + v (可视块模式)
  • 使用向上/向下箭头键select你想要的行(它不会突出显示所有内容 – 没关系!)
  • Shift + (首都I)
  • 插入你想要的文字,即'%'
  • Esc

给它一秒钟的工作。


在vim中取消注释块:

  • Esc (离开编辑或其他模式)
  • 点击ctrl + v (可视块模式)
  • 使用上/下箭头键select要取消注释的行。

    如果要select多个字符,请使用一个或组合这些方法:

    • 使用左/右箭头键select更多的文字
    • select文本块使用Shift +向左/向右箭头键
    • 您可以反复按下下面的删除键,就像一个常规的删除button
  • dx删除字符,必要时重复

  • Esc

给它一秒钟的工作。

有时候,我被装进了一个遥控盒,我的插件和.vimrc无法帮助我,或者有时NerdCommenter错误(例如embedded在html中的JavaScript)。

在这些情况下,低技术替代scheme是内置的norm命令,它只是在指定范围的每一行运行任意的vim命令。 例如:

评论 #

 1. visually select the text rows (using V as usual) 2. :norm i# 

这在每行的开始插入“#”。 请注意,当你input:范围将被填充,所以它会看起来像:'<,'>norm i#

取消注释 #

 1. visually select the text as before (or type gv to re-select the previous selection) 2. :norm x 

这将删除每行的第一个字符。 如果我使用了2-char注释(比如//),那么我只需要:norm xx删除两个字符。

如果注释是在OP的问题中缩进的,那么你可以像这样定位你的删除:

 :norm ^x 

意思是“去第一个非空格字符,然后删除一个字符”。

注意 :由于norm只是执行常规的vim命令,所以你不仅仅限于注释,你可以对每行进行一些复杂的编辑。 如果您需要将转义字符作为命令序列的一部分,请键入ctrl-v,然后点击转义键。

注2 :当然,如果你发现自己正在使用norm你当然也可以添加一个映射。 例如把下面一行放在〜/ .vimrc中,可以让你在做视觉select之后inputctrl-n而不是:norm

 vnoremap <Cn> :norm 

注3 :裸机vim有时并没有编译成norm命令,所以一定要使用更强的版本,通常是/ usr / bin / vim,而不是/ bin / vi

(感谢@Manbroski和@rakslice对这个答案的改进)

我在.vimrc有以下内容:

 " Commenting blocks of code. autocmd FileType c,cpp,java,scala let b:comment_leader = '// ' autocmd FileType sh,ruby,python let b:comment_leader = '# ' autocmd FileType conf,fstab let b:comment_leader = '# ' autocmd FileType tex let b:comment_leader = '% ' autocmd FileType mail let b:comment_leader = '> ' autocmd FileType vim let b:comment_leader = '" ' noremap <silent> ,cc :<CB>silent <CE>s/^/<CR>=escape(b:comment_leader,'\/')<CR>/<CR>:nohlsearch<CR> noremap <silent> ,cu :<CB>silent <CE>s/^\V<CR>=escape(b:comment_leader,'\/')<CR>//e<CR>:nohlsearch<CR> 

现在,您可以键入,cc来注释一行,并且,cu取消注释行(在正常和可视模式下都可以)。

(我多年前从一些网站上偷了它,所以我不能完全解释它是如何工作的:)。 有解释的地方有评论 。)

在vim中指定要注释的行:

显示行号:

 :set number 

然后

 :5,17s/^/#/ this will comment out line 5-17 

或这个:

 :%s/^/#/ will comment out all lines in file 

下面是我如何做到这一点:

  1. 转到您想注释的第一行的第一个字符。

  2. 在GVIM中按Ctrl + q或在VIM中按Ctrl + v ,然后向下select行中的第一个字符以注释掉。

  3. 然后按c ,然后添加注释字符。

取消注释工作方式相同,只需键入空格而不是注释字符。

我已经想出了一个简单的补充,我的.vimrc文件工作得很好,可以很容易地扩展。 您只需将一个新的文件types添加到comment_map及其评论组长。

我添加了一个映射到正常和可视模式,但是你可以重新映射到任何你喜欢的东西。 我只喜欢有一个“切换”风格的function。 一个拥有多个映射等

 let s:comment_map = { \ "c": '\/\/', \ "cpp": '\/\/', \ "go": '\/\/', \ "java": '\/\/', \ "javascript": '\/\/', \ "lua": '--', \ "scala": '\/\/', \ "php": '\/\/', \ "python": '#', \ "ruby": '#', \ "rust": '\/\/', \ "sh": '#', \ "desktop": '#', \ "fstab": '#', \ "conf": '#', \ "profile": '#', \ "bashrc": '#', \ "bash_profile": '#', \ "mail": '>', \ "eml": '>', \ "bat": 'REM', \ "ahk": ';', \ "vim": '"', \ "tex": '%', \ } function! ToggleComment() if has_key(s:comment_map, &filetype) let comment_leader = s:comment_map[&filetype] if getline('.') =~ "^\\s*" . comment_leader . " " " Uncomment the line execute "silent s/^\\(\\s*\\)" . comment_leader . " /\\1/" else if getline('.') =~ "^\\s*" . comment_leader " Uncomment the line execute "silent s/^\\(\\s*\\)" . comment_leader . "/\\1/" else " Comment the line execute "silent s/^\\(\\s*\\)/\\1" . comment_leader . " /" end end else echo "No comment leader found for filetype" end endfunction nnoremap <leader><Space> :call ToggleComment()<cr> vnoremap <leader><Space> :call ToggleComment()<cr> 

注意:

我不使用任何callback或挂钩到文件types/加载,因为我发现他们减慢Vim的启动超过.vimrc静态函数/地图,但这只是我的首选项。 我也试图保持简单和高性能。 如果你使用自动命令,你需要确保将它们放在一个自动命令组中,否则callback被加载到文件types多次加载每个文件,并导致大量的性能下降。

使用Control-Vselect文本的矩形:转到第一个#字符,键入Ctrl + V ,向右移动一次,然后向下移动,直到注释的结尾。 现在键入x :你正在删除所有的#字符,后面跟一个空格。

这里是我的.vimrc

 "insert and remove comments in visual and normal mode vmap ,ic :s/^/#/g<CR>:let @/ = ""<CR> map ,ic :s/^/#/g<CR>:let @/ = ""<CR> vmap ,rc :s/^#//g<CR>:let @/ = ""<CR> map ,rc :s/^#//g<CR>:let @/ = ""<CR> 

在正常和可视模式下,这让我按ic键插入注释,rc删除注释。

先按 – > clt + v

按需要向上或向下按箭头键

然后按 – > shift + i

然后使用 – > shift +#插入注释

退出

切换评论

如果你需要的是切换评论,我宁愿与tnote的 commentary.vim去。

在这里输入图像描述

安装

病原:

 cd ~/.vim/bundle git clone git://github.com/tpope/vim-commentary.git 

VIM插头:

 Plug 'tpope/vim-commentary' 

Vundle:

 Plugin 'tpope/vim-commentary' 

进一步的定制

将其添加到.vimrc文件中: noremap <leader>/ :Commentary<cr>

你现在可以通过按Leader + /来切换注释,就像Sublime和Atom一样。

CLT + V

使用箭头键下拉

希夫+我

按shift +#

退出

然后等待并完成

我喜欢使用tcomment插件: http : //www.vim.org/scripts/script.php? script_id=1173

我已经映射gc和gcc来评论一行或一个突出显示的代码块。 它检测到文件types,工作得很好。

我使用EnhancedCommentify 。 它评论我需要的一切(编程语言,脚本,configuration文件)。 我用它与视觉模式绑定。 只需select你想评论的文本,然后按co / cc / cd。

 vmap co :call EnhancedCommentify('','guess')<CR> vmap cc :call EnhancedCommentify('','comment')<CR> vmap cd :call EnhancedCommentify('','decomment')<CR> 

如果你已经知道行号,那么n,ms/# //将起作用。

我标记第一行和最后一行(ma和mb),然后执行:'a,'bs / ^#//

有30个答案在我面前,我会尝试给出一个更简单的解决scheme:在行的开头插入一个# 。 然后沿着一条线并按点( . )。 重复,做jj 等等…要取消注释,请删除一个# (您可以在#点击x ),然后使用k ,进行相反操作. ,等等…

如何在vi中取消以下三行注释:

 #code code #code #code code code 

将光标放在左上方的#符号上并按下Ctrl + V。 这使你进入可视化块模式。 按向下箭头或j三次以select所有三行。 然后按d 。 所有的评论消失。 要撤消,请按u

如何在vi中评论以下三行:

 code code code code code code 

将光标放在左上angular的字符上,按下Ctrl + V。 这使你进入可视化块模式。 按向下箭头或j三次以select所有三行。 然后按:

I// Esc

这是一个资本我,和逃避。

当您按Esc时,所有选定的行将会得到您指定的注释符号。

我使用蒂姆·波普的vim评论插件。

我使用Jasmeet Singh Anand的comments.vim (在vim.org上find),

它与c,c ++,java,php,proc,css,html,htm,xml,xhtml,vim,vimrc,sql,sh,ksh,csh,perl,tex,fortran,ml,caml,ocaml, VHDL,haskel和普通文件

它在正常和可视模式下注释和取消注释不同源文件中的行

用法:

  • ctrl-c注释一行
  • ctrl-x 取消注释一行
  • shift-v并select多行,然后按ctrl-c注释选中的多行
  • shift-v并select多行,然后ctrl-x取消select多行的注释

我把菲尔和jqno的答案结合起来,并用空格来解释评论:

 autocmd FileType c,cpp,java,scala let b:comment_leader = '//' autocmd FileType sh,ruby,python let b:comment_leader = '#' autocmd FileType conf,fstab let b:comment_leader = '#' autocmd FileType tex let b:comment_leader = '%' autocmd FileType mail let b:comment_leader = '>' autocmd FileType vim let b:comment_leader = '"' function! CommentToggle() execute ':silent! s/\([^ ]\)/' . b:comment_leader . ' \1/' execute ':silent! s/^\( *\)' . b:comment_leader . ' \?' . b:comment_leader . ' \?/\1/' endfunction map <F7> :call CommentToggle()<CR> 

这个简单的片段来自我的.vimrc:

 function! CommentToggle() execute ':silent! s/\([^ ]\)/\/\/ \1/' execute ':silent! s/^\( *\)\/\/ \/\/ /\1/' endfunction map <F7> :call CommentToggle()<CR> 

这是/ – 评论,但你可以很容易地适应其他angular色。 你可以使用autocmd来设置一个领导者为jqnobuild议。

这是一个非常简单而有效的方法,自然地处理范围和视觉模式。

他们最快最直观的方法就是对线条进行重新评估,然后(对于走路 – 取消注释),尝试一下,你就不会回头了。

RubyBash中 ,使用2个空格缩进:

 map ) I# <Esc>j map ( k^2x 

C / C ++PHP中 ,使用4个空格缩进:

 map ) I// <Esc>j map ( k^4x 

缺点是你失去()移动句子(但das可以在那里填写),你会偶尔回退select和replace或Ctrl-V处理长篇章。 但是这很less见。

对于C风格,最长的评论最好的处理方式是:

 set cindent set formatoptions=tcqr 

…与使用V[move]gq很好地结合来重做词语包装。

我为此使用vim-multiple-cursors 。

  1. 要select区域,请按0 (即零,不是字母“o”)转到要注释的区域的第一行或最后一行的第一个字符。 然后按V并使用JK或上下方向键select区域。
  2. 然后通过按下Ctrl N将虚拟光标放在select的每一行上。
  3. 然后按I同时编辑select的每一行。

是的,这个问题已经有33个(主要是重复的)答案。

这里是另一种如何在Vim中发表评论的方法: 动作 。 基本的想法是使用相同的方法,通过键入yip或通过键入dj删除2行来对注释进行注释或取消注释。

这种方法可以让你做这样的事情:

  • ccj评论接下来的两行, cuk取消注释;

  • cci{评论封锁和cui{取消注释;

  • ccip评论一个整段,并cuip去注释它。

  • ccG评论一切,直到最后一行,并cugg取消注释一切到第一行。

所有你需要的是对运动进行操作的 2个函数,以及每个函数的2个映射。 首先,映射:

 nnoremap <silent> cc :set opfunc=CommentOut<cr>g@ vnoremap <silent> cc :<cu>call CommentOut(visualmode(), 1)<cr> nnoremap <silent> cu :set opfunc=Uncomment<cr>g@ vnoremap <silent> cu :<cu>call Uncomment(visualmode(), 1)<cr> 

(请参阅关于g@操作符和operatorfuncvariables的手册。)

而现在的function:

 function! CommentOut(type, ...) if a:0 silent exe "normal! :'<,'>s/^/#/\<cr>`<" else silent exe "normal! :'[,']s/^/#/\<cr>'[" endif endfunction function! Uncomment(type, ...) if a:0 silent exe "normal! :'<,'>s/^\\(\\s*\\)#/\\1/\<cr>`<" else silent exe "normal! :'[,']s/^\\(\\s*\\)#/\\1/\<cr>`[" endif endfunction 

修改上面的正则expression式,以适应你的口味#应该在哪里:

从这里的答案开始,我开始了自己的评论function。 它打开和closures评论。 它可以处理像//print('blue'); //this thing is blue //print('blue'); //this thing is blue ,只是切换第一个评论。 此外,它增加了评论和一个空间,只是第一个非空白的地方,而不是在行的开始。 此外,它不会不必要地复制空格,但使用缩放(:h \ zs帮助)来避免这种额外的工作,当注释和缩进行。 希望它能帮助一些极简主义者。 欢迎提出build议。

 autocmd FileType c,cpp,java let b:comment_leader = '\/\/' autocmd FileType arduino let b:comment_leader = '\/\/' autocmd FileType sh,ruby,python let b:comment_leader = '#' autocmd FileType conf,fstab let b:comment_leader = '#' autocmd FileType matlab,tex let b:comment_leader = '%' autocmd FileType vim let b:comment_leader = '"' function! ToggleComment() " help with :h \v or pattern-atoms if exists('b:comment_leader') if getline('.') =~ '\v^\s*' .b:comment_leader " uncomment the line execute 'silent s/\v^\s*\zs' .b:comment_leader.'[ ]?//g' else " comment the line execute 'silent s/\v^\s*\zs\ze(\S|\n)/' .b:comment_leader.' /g' endif else echo 'no comment leader found for filetype' end endfunction nnoremap <leader>c :call ToggleComment()<cr> 

你可以通过tpope( https://github.com/tpope/vim-commentary )来使用vim-comment,你可以使用它如下:

按下进入视觉模式

 'v' 

然后按

 'j' repeatedly or eg 4j to select 4 row 

现在,您所要做的与select是input键:

 'gc' 

这将注释掉所有的select,取消注释重复键:

 'gc' 

我喜欢/* ... */ (C ansi评论),所以这里是我的技巧。 当然,你可以调整它以适应不同的情况。


评论与/ * … * /

select文本(去开始,开始视觉块,跳转):

 <cV>} 

input要在select中应用的命令

 :norm i/* <cv><esc>$a */ 

命令将如下所示:: :'<,'>norm i /* ^[$a */

有关详细信息,请参阅(i *)。


取消注释/ * … * /

select文本(像以前一样,或者你喜欢的其他方式):

 <cV>} 

input要在select中应用的命令

 :norm :s-\s*/\*\s*-<cv><enter>$bbld$ 

命令将如下所示:: :'<,'>norm :s-\s*/\*\s*-^M$bbld$

有关详细信息,请参阅(ii *)。


结果

效果是逐行评论:

 Comment block Comment block Comment block 

成为(反之亦然):

 /* Comment block */ /* Comment block */ /* Comment block */ 

最好将它保存为.vimrc map@reg ,因为input的内容很多。 如果您希望单个/**/到整个块,请使用:

用一个/ * * /整个块来评论

把它保存在一个寄存器中,logging下来,比如qc ,然后在一个段落的开头发表评论:

 v}di/* */<esc>hhhp 

不要忘记q ,完成logging。

有关详细信息,请参阅(iii *)。


取消块中的单个/ * * /的注释

将它保存在registry中,比如@u 。 将光标放在块的任何位置,并且:

 ?/\*<enter>xx/\*/<enter>xx 

通过完成q命令保存寄存器。

有关详细信息,请参阅(iv *)。


结果

效果是对多行的单个注释:

 Comment block Comment block Comment block 

成为(反之亦然):

 /* Comment block Comment block Comment block */ 

说明

(i *)通过使用在每个select的行中重复应用相同命令的norm来工作。 该命令只需插入一个/* ,find该行的结尾,并通过插入一个*/

 :norm i/* <cv><esc>$a */ 

(ii *)它也使用norm在每一行上重复search/replace。 searchspaces /* spaces并用spaces /* spacesreplace。 之后,find行结尾,退两个字,右alignment一个字母,删除到最后。

 :norm :s-\s*/\*\s*-<cv><enter>$bbld$ 

(iii *)通过v}select段落,删除它,插入注释打开和closures,移动到中间并粘贴删除的块。

 v}di/* */<esc>hhhp 

(iv *)中间的任何地方,向后找一个/* ,将其删除; find一个*/ ,将其删除。

 ?/\*<enter>xx/\*/<enter>xx 

非常好的问题,但没有太多好的答案恕我直言。 首先,我会说,使用块插入模式在这里不是一个简单的解决scheme,只是太多的击键,所以显然它必须在选定的行上工作,以提高代码编辑的性能。 还有一点没有人提到:评论标志应该放在哪一行?在行的最开始还是在实际的文本之前? 这可能是一个味道的问题,但我认为,应该把它放在文本之前,以保持代码的可读性:当注释符号被放在行的开始,它打破了缩进代码的视觉一致性,所以它看起来像一个项目符号列表。 考虑到这一点,我已经结束了以下解决scheme(我做了#评论的例子)。 在我的vimrc

 vnoremap 1 :s:^\(\s*\)\([^#\t ]\):\1#\2:e<CR> vnoremap 2 :s:^\(\s*\)#\(\s*\):\1\2:e<CR> 

1在每个选定行中的文本之前(在空格之后)插入# 。 它检查是否已经# ,不要插入#两次。 也忽略空行。
密钥2删除一个# 。 它也保持对线右侧的评论安全。


更新 :这里是一个例子,如何使文件types相关的切换评论命令。 要了解有关这些事情的更多信息,请阅读: http : //learnvimscriptthehardway.stevelosh.com/chapters/14.html

为了使它工作,把下面的行放在你的.vimrc文件中。

 " build the whole regex search/replace command function! Build() let b:Comment_ON='''<,''>s:^\(\s*\)\([^\t ]\):\1' . b:cs . '\2:e' let b:Comment_OFF='''<,''>s:^\(\s*\)' . b:cs . '\(\s*\):\1\2:e' endfunction " run this group on Filetype event augroup SetCS autocmd! "default comment sign autocmd FileType * let b:cs='--' "detect file type and assign comment sign autocmd FileType python,ruby let b:cs='#' autocmd FileType c,cpp,java,javascript,php let b:cs = '\/\/' autocmd FileType vim let b:cs='"' autocmd FileType * call Build() augroup END vnoremap 1 :<Cu>execute b:Comment_ON<CR> vnoremap 2 :<Cu>execute b:Comment_OFF<CR>