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

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

class Search < ActiveRecord::Migrationdef 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# endend
def self.down# drop_table :searchesendend

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

一般来说,我正在寻找一种简单而流畅的方法来注释和取消注释行。这里我处理的是Ruby代码,但它可以是JavaScript(//)或Haml(-#)。

1220342 次浏览

如果你已经知道行号,那么n,ms/# //就可以了。

以下是我的.vimrc

"insert and remove comments in visual and normal modevmap ,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删除注释。

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

我是这样做的:

  1. 转到要注释掉的第一行的第一个字符。

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

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

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

以下是我的.vimrc

" Commenting blocks of code.augroup commenting_blocks_of_codeautocmd!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 = '" 'augroup ENDnoremap <silent> ,cc :<C-B>silent <C-E>s/^/<C-R>=escape(b:comment_leader,'\/')<CR>/<CR>:nohlsearch<CR>noremap <silent> ,cu :<C-B>silent <C-E>s/^\V<C-R>=escape(b:comment_leader,'\/')<CR>//e<CR>:nohlsearch<CR>

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

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

对于这些任务,我大部分时间都使用块选择

将光标放在第一个#字符上,按CtrlV(或gVim的CtrlQ),然后向下走,直到最后一个注释行并按x,这将垂直删除所有#字符。

对于注释文本块几乎是相同的:

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

默认情况下,对于debian/ubuntu附带的vim精简版,请在第三步中键入: s/^/#(每行第一个字符的任何剩余突出显示都可以用:nohl删除)。

这里有两个小屏幕录音供视觉参考。

评论:评论

取消评论:取消注释

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

我已经映射了gc和gcc来注释一行或突出显示的代码块。它检测文件类型并且运行得非常好。

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

评论数所示:

对于任何对用法感到困惑的人,默认的领导者是“\”,因此10\cc将注释十行,10\cu将取消注释这十行

我使用修改内容。它注释了我需要的一切(编程语言、脚本、配置文件)。我将它与可视模式绑定一起使用。只需选择要注释的文本并按co/cc/cd。

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

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

"comment (cc) and uncomment (cu) codenoremap   <silent> cc      :s,^\(\s*\)[^# \t]\@=,\1# ,e<CR>:nohls<CR>zvjnoremap   <silent> cu      :s,^\(\s*\)# \s\@!,\1,e<CR>:nohls<CR>zvj

您可以使用#注释/取消注释单行或多行。要执行多行操作,请选择行,然后键入cc/cu快捷方式,或键入数字然后cc/cu,例如7cc将注释光标中的7行。

我从在Vim中注释/取消注释ruby代码块的最优雅方式是什么?上的人那里得到了原始代码,并做了一些小的更改(更改了快捷键,并在#之后添加了一个空格)。

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

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

它用于//-注释,但您可以轻松地将其调整为其他字符。您可以按照jqno的建议使用autocmd设置领导者。

这是一种非常简单有效的方式,自然地使用范围和视觉模式。

在vim中注释掉块:

  • Esc(离开编辑或其他模式)
  • 命中ctrl+v(可视块模式)
  • 使用/箭头键选择您想要的行(它不会突出显示所有内容-没关系!)
  • Shift+(大写I)
  • 插入您想要的文本,例如%
  • EscEsc

在vim中取消注释块:

  • Esc(离开编辑或其他模式)
  • 命中ctrl+v(可视块模式)
  • 使用/箭头键选择要取消注释的行。

    如果要选择多个字符,请使用一个或组合以下方法:

    • 使用左/右箭头键选择更多文本
    • 要选择文本块,请使用Shift+/箭头键
    • 您可以反复按下下面的删除键,就像普通的删除按钮一样

    • 删除字符,必要时重复

我使用comments.vim贾斯梅特·辛格·阿南德(在vim.org找到),

它适用于C,C++,Java,PHP[2345],proc,CSS,超文本标记语言,htm,XML,XHTML,vim,vimrc,SQL,sh,ksh,csh,Perl,tex,fortran,ml,caml,ocaml,vhdl,haskel和普通文件

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

用法:

  • CtrlC评论单行
  • CtrlX取消评论单行
  • ShiftV并选择多行,然后CtrlC注释选定的多行
  • ShiftV并选择多行,然后CtrlX取消注释选定的多行

指定要在vim中注释的行:

显示行号:

:set number

然后

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

或者这个:

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

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

#code code#code#code code code

将光标放在左上角的#符号上,然后按CtrlV。这将使您处于可视块模式。按向下箭头或J三次以选择所有三行。然后按D。所有注释消失。要撤消,请按U

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

code codecodecode code code

将光标放在左上角字符上,按CtrlV。这使您处于视觉块模式。按J三次以选择所有三行。然后按:

////Esc

这是一个资本I,//,和逃避。

当您按ESC时,所有选定的行都将获得您指定的注释符号。

这些命令可以处理任何语言的注释。

@CMS的解决方案是最“vim原生”的注释输入/输出行的方式。在@CMS的第二步中,在CtrlV之后,您还可以使用r#添加注释或x删除注释。Drew Neil的实用Vim,第46页很好地解释了这种技术。

另一个好的选择是使用ex mode命令。:[范围]正常##。显然,要使用这个保存击键,您需要注释掉15多行。

我使用Tim Pope的vim系统评论插件。

我结合了Phil和jqno的答案,用空格做了untoggle注释:

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/\([^ ]\)/' . escape(b:comment_leader,'\/') . ' \1/'execute ':silent! s/^\( *\)' . escape(b:comment_leader,'\/') . ' \?' . escape(b:comment_leader,'\/') . ' \?/\1/'endfunctionmap <F7> :call CommentToggle()<CR>

它是如何工作的:

假设我们使用#-注释。

第一个命令s/\([^ ]\)/# \1/搜索第一个非空格字符[^ ]并将其替换为# +itself。自身替换由搜索模式中的\(..\)和替换模式中的\1完成。

第二个命令s/^\( *\)# \?# \?/\1/搜索以双注释^\( *\)# \?# \?开头的行(接受注释之间的0或1个空格),并简单地用非注释部分\( *\)替换那些行(意味着前面的空格数量相同)。

有关vim模式的更多详细信息,请查看这个

有时我会陷入一个远程盒子,我的插件和. vimrc无法帮助我,或者有时NerdCommenter会出错(例如嵌入在超文本标记语言中的JavaScript)。

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

评论与#

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

这将在每行的开头插入“#”。请注意,当您键入:时,范围将被填充,因此它看起来真的像:'<,'>norm i#

无评论#

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

这会删除每行的第一个字符。如果我使用了2个字符的注释,例如//,那么我只需执行:norm xx来删除两个字符。

如果注释像OP的问题一样缩进,那么你可以像这样锚定删除:

:norm ^x

这意味着“转到第一个非空格字符,然后删除一个字符”。请注意,与块选择不同,即使注释缩进不均匀,这种技术也有效!

说明:由于norm实际上只是执行常规的vim命令,你不仅限于注释,你还可以对每行进行一些复杂的编辑。如果你需要转义字符作为命令序列的一部分,键入ctrl-v,然后点击转义键(或者更简单,只需记录一个快速宏,然后在每一行上使用规范执行该宏)。

附注2:如果您发现自己经常使用norm,您当然也可以添加映射。例如,在~/. vimrc中添加以下行,您可以在进行视觉选择后键入ctrl-n而不是:norm

vnoremap <C-n> :norm

附注3:裸骨vim有时没有编译norm命令,所以一定要使用增强版本,即通常 /usr/bin/vim,而不是 /bin/vi

(感谢@Manbroski和@rak的改进纳入这个答案)

我想出了一个简单的补充到我的. vimrc文件,它工作得很好,可以很容易地扩展。

我添加了一个映射到正常和可视模式,但你可以重新映射到任何你喜欢的。我只喜欢有一个切换风格的功能。一个熊有多个映射等。

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 lineexecute "silent s/^\\(\\s*\\)" . comment_leader . " /\\1/"elseif getline('.') =~ "^\\s*" . comment_leader" Uncomment the lineexecute "silent s/^\\(\\s*\\)" . comment_leader . "/\\1/"else" Comment the lineexecute "silent s/^\\(\\s*\\)/\\1" . comment_leader . " /"endendelseecho "No comment leader found for filetype"endendfunction

nnoremap <leader><Space> :call ToggleComment()<cr>vnoremap <leader><Space> :call ToggleComment()<cr>

备注:

我没有在文件类型/加载中使用任何回调或挂钩,因为我发现它们比.vimrc静态函数/map更慢Vim的启动速度,但这只是我的偏好。我还试图保持它的简单和高性能。如果你确实使用自动命令,你需要确保将它们放在一个自动命令组中,否则回调会在每次加载文件时多次添加到文件类型中,并导致大量性能下降。

从答案中的想法开始,我开始了自己的评论功能。它可以打开和关闭注释。它可以处理//print('blue'); //this thing is blue之类的事情,只需切换第一个注释。此外,它添加注释和一个空格,就在第一个非空格所在的位置,而不是在行的开头。传统上,它不会不必要地复制空格,而是在注释和缩进行时使用缩放(: h\zs for help)来避免这种额外的工作。希望它能帮助一些极简主义者。欢迎提出建议。

" these lines are needed for ToggleComment()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 zsh             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 = '"'
" l:pos   --> cursor position" l:space --> how many spaces we will use b:comment_leader + ' '
function! ToggleComment()if exists('b:comment_leader')let l:pos = col('.')let l:space = ( &ft =~ '\v(c|cpp|java|arduino)' ? '3' : '2' )if getline('.') =~ '\v(\s*|\t*)' .b:comment_leaderlet l:space -= ( getline('.') =~ '\v.*\zs' . b:comment_leader . '(\s+|\t+)@!' ?  1 : 0 )execute 'silent s,\v^(\s*|\t*)\zs' .b:comment_leader.'[ ]?,,g'let l:pos -= l:spaceelseexec 'normal! 0i' .b:comment_leader .' 'let l:pos += l:spaceendifcall cursor(line("."), l:pos)elseecho 'no comment leader found for filetype'endendfunction
nnoremap <Leader>t :call ToggleComment()<CR>inoremap <Leader>t <C-o>:call ToggleComment()<CR>xnoremap <Leader>t :'<,'>call ToggleComment()<CR>

通过mark命令标记文本区域,例如ma和mb类型命令::'a,'bg/(.*)/s//\1/

您可以在此处看到此类测试操作的示例http://bknpk.ddns.net/my_web/VIM/vim_shell_cmd_on_block.html

我个人不喜欢注释“切换”功能,因为它会破坏已经包含在代码中的注释。此外,我希望注释字符总是出现在最左边,这样我就可以很容易地看到注释块。我也希望这是嵌套的(如果我先注释掉一个块,然后是一个封闭块)。因此,我稍微改变了其中一个解决方案。我使用F5进行注释,使用Shift-F5取消注释。此外,我在s/命令末尾添加了一个 /g:

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 = '"'autocmd FileType nasm             let b:comment_leader = ';'
function! CommentLine()execute ':silent! s/^\(.*\)/' . b:comment_leader . ' \1/g'endfunction
function! UncommentLine()execute ':silent! s/^' . b:comment_leader . ' //g'endfunction
map <F5> :call CommentLine()<CR>map <S-F5> :call UncommentLine()<CR>

为此我使用vim多游标

  1. 要选择区域,请按(是零,不是字母“o”)转到要注释掉的区域的第一行或最后一行的第一个字符。然后按V并使用JK或向上和向下箭头键选择区域。
  2. 然后按CtrlN在选择的每一行上放置一个虚拟光标。
  3. 然后按同时编辑选择的每一行。

最快捷、最直观的方法是重新映射)进行行的下移注释,然后重新映射(进行上移注释。尝试一下,你就不会回头了。

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

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

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

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

缺点是你失去了()的句子移动(但das可以填补那里),你偶尔会回到选择和替换或CtrlV来处理长部分。

对于C风格,长注释最好用以下方式处理:

set cindentset formatoptions=tcqr

…这与使用V[move]gq重做换行结合得很好。

非常好的问题,但没有那么多好的答案。首先,我想说,使用块插入模式是这里的首要解决方案,只是击键太多,所以显然它必须在选定的行上工作,以提高代码编辑的性能。另一个没人提到的观点:注释符号应该放在哪里——在行的开头还是在实际文本之前?这可能是一个品味问题,但我的观点是,它应该放在文本之前以保持代码的可读性:当注释符号放在一行开头时,它破坏了缩进代码的视觉一致性,所以它看起来像一个项目符号列表。考虑到这一点,我最终提出了以下解决方案(我为#注释举了一个例子)。在我的vimrc中:

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

Key1在每个选定行的文本之前(空格之后)插入#。它检查是否已经有#,而不是插入#两次。并且还忽略空行。
2删除一个#。它还保持行右侧的注释安全。


更新:这是一个示例,如何使文件类型依赖于切换注释命令。要了解有关这些内容的更多信息,请阅读:http://learnvimscriptthehardway.stevelosh.com/chapters/14.html

为了使其工作,请将以下行放在.vimrc文件中。

" build the whole regex search/replace commandfunction! 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 eventaugroup SetCSautocmd!"default comment signautocmd FileType * let b:cs='--'"detect file type and assign comment signautocmd 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 :<C-u>execute b:Comment_ON<CR>vnoremap 2 :<C-u>execute b:Comment_OFF<CR>

您可以通过tpope(https://github.com/tpope/vim-commentary)使用vim评论,您可以按以下方式使用它:

通过按下进入可视模式

'v'

然后按

'j' repeatedly or e.g 4j to select 4 row

现在你所要做的就是输入键:

'gc'

这将注释掉所有选择,取消注释重复键:

'gc'

我喜欢/* ... */(C ansi注释),所以这是我给你的技巧。当然,您可以调整它以在不同的情况下使用。


评论/*…*/

选择文本(转到开始,开始视觉块,跳转}):

<c-V>}

键入要在选择中应用的命令

:norm i/* <c-v><esc>$a */

命令看起来像::'<,'>norm i /* ^[$a */

详情见(i*)。


取消注释/*…*/

选择文本(如前所述,或您喜欢的其他方式):

<c-V>}

键入要在选择中应用的命令

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

命令看起来像::'<,'>norm :s-\s*/\*\s*-^M$bbld$

详情见(ii*)。


结果

效果是一行一行的评论:

Comment blockComment blockComment block

成为(反之亦然):

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

最好将其保存为.vimrc中的map@reg,因为要输入的内容很多。如果您更喜欢单个/**/而不是整个块,请使用:

用单个 /* */ 整个块进行评论

将其保存在寄存器中,例如记录qc,然后在段落的开头进行评论:

v}di/*  */<esc>hhhp

不要再忘记q,完成记录。

详情见(iii*)。


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

将其保存在寄存器中,例如@u。将光标放在块内的任何位置,然后:

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

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

详情见(iv*)。


结果

效果是多行的单个注释:

Comment blockComment blockComment block

成为(反之亦然):

/* Comment blockComment blockComment block */

解释

(i*)它的工作原理是使用norm,它在每个选定的行中重复应用相同的命令。该命令只需插入一个/*,找到该行的末尾,并通过插入一个*/完成

:norm i/* <c-v><esc>$a */

(二*)它还使用norm在每一行重复搜索/替换。搜索spaces /* spaces并用无替换。之后,找到行尾,返回两个单词,正确一个字母,删除到末尾。

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

(三*)通过v}选择段落,删除它,插入注释打开和关闭,移动到中间并粘贴已删除的块。

v}di/*  */<esc>hhhp

(四*)中间的任何地方,向后找到/*,删除它;向前找到*/,删除它。

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

是的,这个问题已经有33个(大部分是重复的)答案。

这是另一种在Vim中注释行的方法:动议。基本思想是使用与键入yip或键入dj删除2行相同的方法来注释或取消注释行。

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

  • ccj注释接下来的2行,cuk取消注释;

  • cci{注释一个块,cui{取消注释;

  • ccip注释整段,cuip取消注释。

  • ccG注释所有内容到最后一行,cugg取消注释所有内容到第一行。

您只需要2个对动作进行操作的函数,以及每个函数的2个映射。首先,映射:

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

(请参阅有关g@运算符和operatorfunc变量的手册。)

现在的功能:

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

修改上面的正则表达式以适应您的口味,即#应该在哪里:

前面有30个答案,我将尝试给出一个更简单的解决方案:在一行的开头插入一个#。然后沿着一行向下按点(.)。重复,做j.j.等…要取消注释,删除一个#(你可以在#上按x),然后使用k.等做相反的操作…

此解决方案将/映射到注释和?映射到取消注释(使用单个映射切换注释太复杂而无法正确实现)。它从VIM的内置commentstring选项中获取注释字符串,如果声明filetype plugin on,则从/usr/share/vim/vim*/ftplugin/*.vim等文件中填充。

filetype plugin onautocmd FileType * let b:comment = split(&commentstring, '%s', 1)autocmd FileType * execute "map <silent> <Leader>/ :normal 0i" . b:comment[0] . "<C-O>$" . b:comment[1] . "<C-O>0<CR>"autocmd FileType * execute "map <silent> <Leader>? :normal $" . repeat('x', strlen(b:comment[1])) . "0" . strlen(b:comment[0]) . "x<CR>"

%s/^/ \ / \ / /g

删除字符之间的sapces和使用此命令注释。C或CPP文件

注释一行(适用于所有语言):

  • noremap <silent> ,// :call CommentLine() <CR>

我们可以用行数调用它,在视觉模式中也可以,它可以工作。就像:要注释四行,请使用4、//,取消注释请使用4,/

取消注释一行(适用于所有语言):

  • noremap <silent> ,/ :call UnCommentLine() <CR>

如果您想在函数中添加新符号[注释]然后添加一个列表并添加一些行。如果您想添加具有已在其中一个列表中定义的注释符号的语言,只需在相应列表中添加您的语言名称(获取正确名称:在vim中打开您的文件并使用: set ft获取您的语言的正确名称)。

评论线的定义()

函数!CommentLine()slash_ft_list=['c','cpp','java','scala','system verilog','verilog','verilog_systemverilog']hash_ft_list=['sh','ruby','python','csh','conf','fstab','perl']perct_ft_list=['tex']让mail_ft_list=['mail']quote_ft_list=['vim']if(索引(slash_ft_list,&ft) ! = -1):规范I//elseif(索引(hash_ft_list,&ft) ! = -1):规范一#elseif(索引(perct_ft_list,&ft) ! = -1)标准I%elseif(索引(mail_ft_list,&ft) ! = -1):规范I>elseif(索引(quote_ft_list,&ft) ! = -1)规范一"endifend函数

UnCommentLine()的定义

函数!UnCommentLine()slash_ft_list=['c','cpp','java','scala','system verilog','verilog','verilog_systemverilog']hash_ft_list=['sh','ruby','python','csh','conf','fstab','perl']perct_ft_list=['tex']让mail_ft_list=['mail']quote_ft_list=['vim']if(索引(slash_ft_list,&ft) ! = -1):范数^2xelseif(索引(hash_ft_list,&ft) ! = -1):范数^xelseif(索引(perct_ft_list,&ft) ! = -1):范数^xelseif(索引(mail_ft_list,&ft) ! = -1):范数^xelseif(索引(quote_ft_list,&ft) ! = -1):范数^xendifend函数

切换评论

如果你只需要切换评论,我宁愿用commentary.vimtpope

在此处输入图片描述

安装

病原体:

cd ~/.vim/bundlegit 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一样。

:vnoremap <C-k><C-c> :norm i//<Cr>:vnoremap <C-k><C-u> :s/\/\///g<Cr>:noh<Cr>

  • 突出显示您的文本并按:,这将显示为:<,'>
  • 在此处键入注释:<,'>Commentary并按输入
  • 繁荣。你完成了芽。

尽管这个问题已经有了很多答案,但我仍然认为我会对我写的一个小插件大喊大叫:赞扬

使用commentstring设置来决定如何注释出代码块,因此您不必在配置中保留不同注释类型的映射,并且支持基于行的注释(例如,//)和块注释(例如,/* */)。

它还为注释和取消注释块映射相同的快捷方式(默认为ctrl+c),因此您不必记住两个映射或一组复杂的命令。

这是一个基本的单行代码,基于上面概述的C-v后跟I方法。

此命令(:Comment)将选定的字符串添加到任何选定行的开头。

command! -range -nargs=1 Comment :execute "'<,'>normal! <C-v>0I" . <f-args> . "<Esc><Esc>"

将此行添加到.vimrc以创建一个命令,该命令接受单个参数并将参数放在当前选择中每行的开头。

例如,如果选择以下文本:

12

你运行这个::Comment //,结果将是:

//1//2

我使用vim 7.4,这对我有用。
假设我们正在注释/取消注释3行。

评论:

如果该行开头没有制表符/空格:
ctrl + V然后jjj然后shift + I (cappital i)然后//然后esc esc
如果该行开头有制表符/空格,您仍然可以执行上述操作或交换为c
ctrl + V然后jjj然后c然后//然后esc esc

取消评论:

如果行的开头没有制表符/空格:
ctrl + V然后jjj然后ll (lower cap L)然后c

如果行的开头有制表符/空格,那么你可以在一个上面空格,然后esc
ctrl + V然后jjj然后ll (lower cap L)然后c然后space然后esc

如果您无法安装插件,但您仍然希望您的注释字符遵循现有的缩进级别,此答案最有用。

这个答案是在这里1)显示正确的代码粘贴到.vimrc中,让vim 7.4+进行块注释/取消注释,同时保持缩进级别,在视觉模式下使用1个快捷方式,2)解释它。代码如下:

let b:commentChar='//'autocmd BufNewFile,BufReadPost *.[ch]    let b:commentChar='//'autocmd BufNewFile,BufReadPost *.cpp    let b:commentChar='//'autocmd BufNewFile,BufReadPost *.py    let b:commentChar='#'autocmd BufNewFile,BufReadPost *.*sh    let b:commentChar='#'function! Docomment ()"make comments on all the lines we've grabbedexecute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'endfunctionfunction! Uncomment ()"uncomment on all our linesexecute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'endfunctionfunction! Comment ()"does the first line begin with a comment?let l:line=getpos("'<")[1]"if there's a matchif match(getline(l:line), '^\s*'.b:commentChar)>-1call Uncomment()elsecall Docomment()endifendfunctionvnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>

它是如何工作的:

  • let b:commentChar='//':这会在vim中创建一个变量。这里的b指的是范围,在这种情况下包含在缓冲区中,这意味着当前打开的文件。您的注释字符是字符串,需要用引号包装,引号不是切换注释时将替换的内容的一部分。

  • autocmd BufNewFile,BufReadPost *...:自动命令触发不同的东西,在这种情况下,这些是在新文件或读取的文件以某个扩展名结束时触发的。触发后,执行以下命令,这允许我们根据文件类型更改commentChar。还有其他方法可以做到这一点,但它们对新手(像我一样)更困惑。

  • function! Docomment():函数以function开头,以endfunction结尾。函数必须以大写开头。!确保此函数使用此版本的Docomment()覆盖任何先前定义为Docomment()的函数。没有!,我出错了,但这可能是因为我正在通过vim命令行定义新函数。

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e':执行调用一个命令。在这种情况下,我们正在执行substitute,它可以采用一个范围(默认情况下这是当前行),例如%用于整个缓冲区,或'<,'>用于突出显示的部分。^\s*是正则表达式,用于匹配一行的开头,后跟任意数量的空格,然后附加到(由于&)。这里的.用于字符串连接,因为escape()不能用引号包装。escape()允许您通过在commentChar中以substitute0开头来转义与参数(在本例中为substitute0和substitute1)匹配的字符。在此之后,我们再次与substitute字符串的末尾连接,该字符串具有substitute4标志。该标志允许我们静默失败,这意味着如果我们在给定行上没有找到匹配项,我们不会大喊大叫。作为一个整体,这一行允许我们在第一个文本之前放置一个注释字符,后跟一个空格,这意味着我们保持缩进级别。

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e':这类似于我们上一个巨大的长命令。这次唯一的是,我们有\v,它确保我们不必转义(),和1,它指的是我们用()创建的组。基本上,我们匹配一行以任意数量的空格开头,然后是我们的注释字符,后跟任意数量的空格,我们只保留第一组空格。同样,如果该行没有注释字符,e让我们默默失败。

  • let l:line=getpos("'<")[1]:这设置了一个变量,就像我们对注释字符所做的那样,但l指的是局部范围(此函数的局部范围)。getpos()获取的位置,在这种情况下,我们突出显示的开始,[1]意味着我们只关心行号,而不关心列号等其他事情。

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1:你知道if是如何工作的。match()检查第一件事是否包含第二件事,所以我们抓住我们开始突出显示的行,并检查它是否以空格开头,后跟注释字符。match()返回this为真的索引,如果没有找到匹配,则返回-1。由于if评估所有非零数字为真,我们必须比较我们的输出,看看它是否大于-1。vim中的比较返回0如果为假,1如果为真,这是if希望看到的正确评估。

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>vnoremap表示以可视模式映射以下命令,但不要递归映射(意味着不要更改可能以其他方式使用的任何其他命令)。基本上,如果你是一个vim新手,总是使用noremap来确保你不会破坏东西。<silent>的意思是“我不想要你的话,只要你的行动”,并告诉它不要在命令行中打印任何东西。<C-r>是我们正在映射的东西,在这种情况下是ctrl+r(注意,你仍然可以使用C-r正常使用这个映射在正常模式下进行“重做”)。C-u有点令人困惑,但基本上它确保你不会忘记你的视觉突出显示(根据这个答案它使你的命令从'<,'>开始,这就是我们想要的)。<cr>指的是点击enter按钮。我们必须点击一次才能真正调用该函数(否则我们刚刚在命令行上键入vnoremap0,我们必须再次点击它才能让我们的替代品完成所有操作(不太确定为什么,但无论如何)。

不管怎样,希望这有帮助。这将使用任何突出显示的vVC-v,检查第一行是否被注释,如果是,尝试取消注释所有突出显示的行,如果没有,为每行添加额外的注释字符层。这是我想要的行为;我不只是想让它切换块中的每一行是否被注释,所以在关于这个主题的要求多个问题之后,它非常适合我。

:g/.spare[1-9].*/,+2s/^/\/\//

上面的代码将注释掉所有包含“备用”的行和之后的一个数字,并且它将从找到的行中注释两行。更多此类应用请访问:http://vim.wikia.com/wiki/Search_and_replace#Details

取消注释整个文件:

  1. Esc退出插入模式
  2. gg转到第一行的第一个字符
  3. ctrl+V或者ctrl+Shift+v选择当前字符
  4. GShift+g到最后一行
  5. x删除选择

在VIM:

1-按v进入视觉模式。

2-使用箭头选择要评论的块。

3-按:

4-类型's/^/#'

要删除注释,只需将步骤4替换为:

4-类型's/^#//'

一些常规的Vim命令不适用于我在Windows上的设置。ctrl+vctrl+q是其中的一些。我后来发现以下方法适用于取消评论行。

鉴于

一些缩进的评论

   # Practice in Vim# Practice in Vim# Practice in Vim# Practice in Vim# Practice in Vim# Practice in Vim# Practice in Vim

以下方法删除#符号并保留缩进。

方法

将光标移动到第一个注释(箭头或hjkl)。然后应用以下技术之一:

可视块模式(更快)

  • Ctrl+Shift+v进入视觉块模式
  • j来选择垂直线。
  • l包含水平字符(可选)
  • x删除块

搜索/替换+正则表达式

  • 选择具有常规视觉模式的文本,即Shift+v
  • 键入:。您将得到此提示'<,'>
  • 类型regex,例如s/#//用无替换哈希。
    (可选:键入s/# //以包含空格)。
  • 输入

:norm命令

  • 选择具有常规视觉模式的文本,即Shift+v
  • 键入:。您将得到此提示'<,'>
  • 输入命令。键入:norm ^x以删除第一个非空白字符和下一个字符。(可选:如果不缩进,请尝试:norm x:norm ^xx以包含空格)。
  • 输入

g模式

  • 选择具有常规视觉模式的文本,即Shift+v
  • 键入:。您将得到此提示'<,'>
  • 给一个命令。键入g/#/norm! ^x
    (可选:键入g/#/norm! ^xx以包含空格)。
  • 输入

搜索结果

    Practice in VimPractice in VimPractice in VimPractice in VimPractice in VimPractice in VimPractice in Vim

另见

  • 发布删除缩进注释
  • 发布关于如何快速评论w/Vim
  • The Primeagen的教程 ong命令。
  • VimTrick的教程评论代码

视觉和Shift-I对我不起作用。


  1. Using #  - `s/^/#/`
    Using `//` - `s/^/\/\//`

    Using #  - `s/^#//`
    Using `//` - `s/^\/\//`

^-开始

/之后添加字符#在这种情况下\/\/转义为//


更新

我写了一个函数来注释和取消注释当前行<Space><Space>

适用于接下来的10行,例如10<Space><Space>

将其粘贴到. vimrc

function CommentUncomment()let line = getline('.')if line[:1] == "//"norm ^2xelsenorm I//endifendfunction
nnoremap <Space><Space> :call CommentUncomment()<CR>

我喜欢集成难忘方法不依赖于外部脚本…

TLDR
gI(大写i)将光标置于行首的插入模式(无论它是空格还是非空格字符以及防止自动缩进

使用它来快速注释(例如)非连续行,注释符号(例如#//)作为第一个字符,并且没有缩进,通过按下.(点)-->但是如果仍然有自动缩进机制,在插入模式下按下并纠正缩进,并且在操作后转义到正常模式。现在.可用于注释掉行…

长期
我现在意识到(多年后),按gI(大写i)会将光标放在插入模式下的第1列(意思是:在行的开头,无论它是单词还是非单词字符)。

插入注释符号(如#)并按escape-现在可以注释单个非连续行(注释符号作为第一个字符并且没有缩进),同时只需按键盘上的.(点)。

与按0i或仅按I相反,它将注释符号放置在第一个单词字符处,部分也带有不需要的缩进

" commentsaugroup comment_like_a_bossautocmd!autocmd FileType c,cpp,go                let b:comment_leader = '// 'autocmd FileType ruby,python             let b:comment_leader = '# 'autocmd FileType conf,fstab,sh,bash,tmux 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 = '" 'augroup ENDnoremap <silent> ,cc :<C-b>silent <C-e>norm ^i<C-r>=b:comment_leader<CR><CR>noremap <silent> ,uc :<C-b>silent <C-e>norm ^xx<CR>

首先,我要感谢@mike的回答,因为我正在使用它的修改版本。我想发布我的版本,以防有人感兴趣。我的主要功能区别在于它将始终对范围内的每一行执行相同的操作。如果选定的范围包含任何未注释的行,那么每行都添加了一个注释领导。这样,如果你的代码块中有人类可读的注释,它们就不会变得未注释。然后,当你取消注释时,人类可读的文本将保持注释状态,因为它有2个注释领导。完成后还会恢复光标位置。

切换注释函数:

function! ToggleComment() range"Ensure we know the comment leader.if !exists('b:comment_leader')echo "Unknown comment leader."returnendif"Save the initial cursor position, to restore later.let l:inipos = getpos('.')"Make a list of all of the line numbers in the range which are already commented.let l:commented_lines = []for i in range(a:firstline, a:lastline)if getline(i) =~ '^\s*' . b:comment_leaderlet l:commented_lines = add(l:commented_lines, i)endifendfor"If every line in the range is commented, set the action to uncomment."  Otherwise, set it to comment.let l:i1 = index(l:commented_lines, a:firstline)let l:i2 = index(l:commented_lines, a:lastline)if l:i1 >= 0 && l:i2 >= 0 && (l:i2 - l:i1) == (a:lastline - a:firstline)let l:action = "uncomment"elselet l:action = "comment"endif"Loop through the range, commenting or uncommenting based on l:action.for i in range(a:firstline, a:lastline)"Move to line i.exec "exe " . i"Perform the action.if l:action == "comment"exec 'normal! 0i' . b:comment_leaderelseexecute 'silent s,' . b:comment_leader . ',,'endifendfor"Restore the initial position.call setpos('.', l:inipos)endfunction

键映射(注意我将注释键更改为'k'):

noremap <Leader>k :call ToggleComment()<CR>

最后,我将autocmds放在下面的“if”语句和augroup中,但它们没有改变。它们大多只是供参考。

if has("autocmd")augroup autocmdsautocmd!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 zsh             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 = '"'augroup ENDendif

编辑:我从原来的答案中更新了切换注释函数。最重要的是,我修改了正则表达式。在许多情况下,如果字符串中还有另一个注释领导者的实例,它将无法正常工作。我相信它可能必须在前面或后面加上一个空格,但我不记得了。不管怎样,下面是Python的示例错误案例。

print("Hello, World!") # Says hello to the world.

我已经修复了这个问题,并简化了正则表达式。一个副作用是它不再在评论领导者之后添加空格,但这并不困扰我。我为一些变量添加了一个局部声明,我在最初的答案中忘记了。