在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 ,这将垂直删除所有#字符。 
评论一块文字几乎是一样的:
-  首先,转到您要评论的第一行,按Ctrl V。 这将使编辑器处于VISUAL BLOCK模式。
- 然后使用箭头键并select直到最后一行
-  现在按下Shift I ,它将把编辑器置于INSERT模式,然后按# 。 这将添加一个哈希到第一行。
-  然后按Esc (给它一秒),它会在所有其他选定的行上插入一个#字符。
 对于默认带有debian / ubuntu的精简版vim,请在第三步中键入: s/^/# 。 
在vim中注释块:
- 按Esc (离开编辑或其他模式)
- 点击ctrl + v (可视块模式)
- 使用向上/向下箭头键select你想要的行(它不会突出显示所有内容 – 没关系!)
- Shift + 我 (首都I)
- 插入你想要的文字,即'%'
- 按Esc
给它一秒钟的工作。
在vim中取消注释块:
- 按Esc (离开编辑或其他模式)
- 点击ctrl + v (可视块模式)
-  使用上/下箭头键select要取消注释的行。
如果要select多个字符,请使用一个或组合这些方法: - 使用左/右箭头键select更多的文字
- select文本块使用Shift +向左/向右箭头键
- 您可以反复按下下面的删除键,就像一个常规的删除button
 
- 
按d或x删除字符,必要时重复 
- 
按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 
下面是我如何做到这一点:
- 
转到您想注释的第一行的第一个字符。 
- 
在GVIM中按Ctrl + q或在VIM中按Ctrl + v ,然后向下select行中的第一个字符以注释掉。 
- 
然后按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:在行的开头插入一个# 。 然后沿着一条线并按点( . )。 重复,做j  , j 等等…要取消注释,请删除一个# (您可以在#点击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议。
这是一个非常简单而有效的方法,自然地处理范围和视觉模式。
 他们最快最直观的方法就是对线条进行重新评估,然后(对于走路 – 取消注释),尝试一下,你就不会回头了。 
在Ruby或Bash中 ,使用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 。
- 要select区域,请按0 (即零,不是字母“o”)转到要注释的区域的第一行或最后一行的第一个字符。 然后按V并使用J , K或上下方向键select区域。
- 然后通过按下Ctrl N将虚拟光标放在select的每一行上。
- 然后按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>