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

What's a quick way to comment/uncomment lines in Vim?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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中有什么有效的方法可以做到这一点?

一般来说,我在寻找一种简单易行的方式来评论和取消注释行。这里我处理的是Ruby代码,但它可以是javascript(//或haml(-#)。


对于这些任务,我使用大多数时间块选择。

将光标放在第一个#字符上,按ctrlv(或ctrlq表示gvim),然后向下移动到最后一个注释行,按xb,将垂直删除所有#字符。

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

  • 首先,转到要注释的第一行,按ctrlv。这将使编辑器处于VISUAL BLOCK模式。
  • 然后使用箭头键并选择直到最后一行
  • 现在按shifti,将编辑器置于INSERT模式,然后按 。这将向第一行添加哈希。
  • 然后按esc(给它一秒钟),它将在所有其他选中的行上插入一个#字符。
  • 默认情况下,对于debian/ubuntu附带的精简版vim,在第三步中键入: s/^/#

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

    评论:Comment

    Uncomment:Uncomment


    要在VIM中注释块,请执行以下操作:

    • esc(退出编辑或其他模式)
    • 点击ctrl+vbkbd(可视块模式)
    • 使用上/下箭头键选择所需的行(它不会突出显示所有内容-没关系!)
    • shift+(大写I)
    • 插入所需文本,即%
    • escxKBDesc

    要取消VIM中的块注释:

    • esc(退出编辑或其他模式)
    • 点击ctrl+vbkbd(可视块模式)
    • 使用/箭头键选择要取消注释的行。

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

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

    • dx删除字符,必要时重复


    有时我会被解压到一个远程的盒子里,在那里我的插件和.vimrc无法帮助我,或者有时nerdcommenter会出错(例如嵌入在HTML中的javascript)。

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

    #评论:

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

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

    #的注释:

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

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

    如果注释缩进为OP问题中的注释,则可以这样锚定删除:

    1
    :norm ^x

    这意味着"转到第一个非空格字符,然后删除一个字符"。请注意,与块选择不同,即使注释的缩进不均匀,此技术也可以工作!

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

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

    1
    vnoremap <C-n> :norm

    注3:bare bones vim有时没有编译norm命令,因此一定要使用增强的版本,即通常的/usr/bin/vim,而不是/bin/vi

    (感谢@manbroski和@rakslite对本答案的改进)


    我使用书呆子的评论脚本。它允许您在代码中轻松地注释、取消注释或切换注释。

    如评论所述:

    for anyone who is confused by the usage, default leader is"\" so 10\cc will comment ten lines and 10\cu will uncomment those ten lines


    我的电子文档中有以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    " 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 :<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来取消注释一行(在正常和可视模式下都有效)。

    (许多年前我从某个网站上偷了它,所以我不能完全解释它是如何工作的。)这里有一个解释。)


    指定在VIM中要注释的行:

    显示行号:

    1
    :set number

    然后

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

    或者:

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


    我是这样做的:

  • 转到要注释的第一行的第一个字符。

  • 点击gvim中的ctrl+q或vim中的ctrl+v,然后向下选择要注释的行中的第一个字符。

  • 然后按c,并添加注释字符。

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


    我已经为我的.vimrc文件添加了一个简单的附件,它工作得很好,并且可以很容易地扩展。只需将新的文件类型添加到注释映射及其注释前导。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    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>

    注:

    我不在文件类型/加载中使用任何回调或钩子,因为我发现它们比.vimrc静态函数/map更能减慢vim的启动速度,但这只是我的偏好。我也试着保持它的简单和性能。如果确实使用了自动命令,则需要确保将它们放入自动命令组中,否则将回调添加到文件类型中,每次加载文件多次,并导致性能下降。


    切换注释

    如果你只需要切换注释,我宁愿用tpope的commentary.vim。

    enter image description here

    安装

    病菌:

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

    VIM插头:

    1
    Plug 'tpope/vim-commentary'

    Vundle:

    1
    Plugin 'tpope/vim-commentary'

    进一步定制

    把这个加到你的.vimrc文件中:noremap / :Commentary

    现在,您可以按Leader/,就像sublime和atom一样,切换注释。


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


    以下是我的电子文档的一部分。

    1
    2
    3
    4
    5
    "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删除注释。


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

    评论:

    如果行的开头没有制表符/空格:ctrl + Vjjjshift + I (cappital i)//esc esc。如果行的开头有制表符/空格,您仍然可以执行上述操作或交换cctrl + Vjjjc//esc esc。不予置评:

    如果行的开头没有制表符/空格:ctrl + Vjjjll (lower cap L)c

    如果行的开头有制表符/空格,那么您可以将一个空格放在上方,并将EDOCX1[34]ctrl + Vjjjll (lower cap L)cspaceesc


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

    1
    2
    3
    #code code
    #code
    #code code code

    将光标放在左上角的#符号上,然后按ctrlv。这将使您进入可视块模式。按三次向下箭头或j选择所有三行。然后按d。所有的评论都消失了。要撤消,请按u

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

    1
    2
    3
    code code
    code
    code code code

    将光标放在左上角字符上,按ctrlv。这将使您进入可视块模式。按三次j选择所有三行。然后按:

    YKBD//SCAKBD

    这是一个大写的I,//,和逃跑。

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


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

    我已经将gc和gcc映射到注释行或突出显示的代码块。它可以检测文件类型并非常好地工作。


    前面有30个答案,我将尝试给出一个更简单的解决方案:在行首插入一个#。然后沿直线向下按DOT(.)。重复一下,做j.j.等,取消注释,去掉#(你可以在#上打x,用k.等做反向……


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

    下面是如何在vim:motions中注释行的另一种方法。其基本思想是,使用与通过键入yip或通过键入dj删除2行的方法相同的方法,对行进行注释或取消注释。

    这种方法将允许您执行以下操作:

    • ccj将下2行注释掉,cuk将它们取消注释;

    • cci{对封锁进行评论,cui{对封锁进行取消注释;

    • ccip对整个段落进行注释,cuip取消注释。

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

    您所需要的只是两个在运动上运行的函数,以及每个函数的两个映射。首先,映射:

    1
    2
    3
    4
    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变量的手册。)

    现在的功能是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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

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


    我使用EnhancedCommentify。它评论了我所需要的一切(编程语言、脚本、配置文件)。我将它与可视模式绑定一起使用。只需选择要评论的文本,然后按co/cc/cd。

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

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


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


    我使用TimPope的VIM注释插件。


    有一个由tpope开发的改变生命的插件,叫做vim-commentary

    https://github.com/tpope/vim-评论

    此插件提供:

    • 神志正常
    • 适当缩进的注释
    • 不注释空/不必要的行

    用途:

    • 通过Vundle安装(我猜是病原体)。
    • 突出显示文本并按:,显示为:<,'>
    • 此处键入注释:<,'>Commentary,然后按enter
    • 繁荣。你做的蓓蕾。


    我把菲尔和JQNO的回答结合起来,用空格做了一些不连贯的评论:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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>

    这里有一个基于C-v的基本单衬层,然后是上面概述的I方法。

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

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

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

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

    1
    2
    1
    2

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

    1
    2
    //1
    //2

    我使用jasmet singh anand的comments.vim(在vim.org上找到)。

    它使用C、C++、Java、PHP(2345)、PRC、CSS、HTML、HTM、XML、XHTML、VIM、VIMRC、SQL、SH、KSH、CSH、Perl、TEX、FORTRAN、ML、CAML、OCAML、VHDL、Haskeland普通文件。

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

    用途:

    • ctrlc用于注释一行
    • ctrlx取消注释一行
    • shiftv并选择多行,然后ctrlv对所选多行进行注释。
    • shiftv并选择多行,然后ctrlx取消对所选多行的注释。


    从这里的答案开始,我开始了自己的评论功能。它打开和关闭注释。它可以处理像//print('blue'); //this thing is blue这样的事情,只需切换第一条注释。此外,它还添加了注释和一个空格,第一个非空格就在其中,而不是行首。另外,在注释和缩进行时,它不会不必要地复制空白,而是使用缩放(:hzs作为帮助)来避免这项额外工作。希望它能帮助一些极简主义者。欢迎提出建议。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    " 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_leader
                let 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:space
            else
                exec 'normal! 0i' .b:comment_leader .' '
                let l:pos += l:space
            endif
            call cursor(line("."), l:pos)
        else
            echo 'no comment leader found for filetype'
        end
    endfunction

    nnoremap <Leader>t :call ToggleComment()<CR>
    inoremap <Leader>t <C-o>:call ToggleComment()<CR>
    xnoremap <Leader>t :'<,'>call ToggleComment()<CR>


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

    代码如下:好的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 grabbed

      execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
    endfunction
    function! Uncomment ()
     "uncomment on all our lines

      execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
    endfunction
    function! Comment ()
     "does the first line begin with a comment?

      let l:line=getpos("'<")[1]
     "if there's a match

      if match(getline(l:line), '^\s*'.b:commentChar)>-1
        call Uncomment()
      else
        call Docomment()
      endif
    endfunction
    vnoremap <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*是regex,用于匹配行的开头,后跟任意数量的空白,然后将其附加到(由于&)。这里的.用于字符串连接,因为escape()不能用引号括起来。escape()允许您通过在\/前面加一个\来转义commentChar中与参数匹配的字符。在此之后,我们再次连接到substitute字符串的末尾,该字符串具有e标志。这面旗子让我们安静地失败,也就是说,如果我们在一条给定的线上找不到匹配,我们就不会为此大喊大叫。作为一个整体,这一行让我们在第一个文本前面放一个注释字符,后面跟一个空格,这意味着我们保持缩进水平。好的。

    • 埃多克斯一〔28〕号:这和我们上次的一次大长命令很相似。唯一的一个是,我们有\v,它确保我们不必逃离(),和1,它是指我们用()创建的组。基本上,我们匹配的是一行,从任意数量的空白开始,然后是注释字符,然后是任意数量的空白,我们只保留第一组空白。同样,如果我们没有评论角色,那么e会让我们安静地失败。好的。

    • let l:line=getpos("'<")[1]:这设置了一个变量,就像我们在注释字符中设置的那样,但是l是指本地范围(此函数的本地范围)。在本例中,getpos()得到突出显示的开始位置,而[1]意味着我们只关心行号,而不关心列号等其他内容。好的。

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

    • vnoremap :call Comment()vnoremap表示在可视模式下映射以下命令,但不要递归映射(也就是说,不要更改任何其他可能以其他方式使用的命令)。基本上,如果你是一个VIM新手,一定要用noremap来确保你不会弄坏东西。的意思是"我不想要你的话,只是你的行动",并告诉它不要把任何东西打印到命令行。是我们要映射的东西,在本例中是ctrl+r(注意,在正常模式下,使用此映射,您仍然可以正常使用c-r来"重做")。C-u有点让人困惑,但基本上它可以确保你不会忘记你的视觉突出显示(根据这个答案,它使你的命令从'<,'>开始,这是我们想要的)。call这里只告诉vim执行我们命名的函数,指点击enter按钮。我们必须点击一次才能真正调用函数(否则我们只是在命令行上键入call function()),我们必须再次点击它才能让我们的替代者一路通过(不确定原因,但无论如何)。好的。

    无论如何,希望这能有所帮助。这将获取用vvC-v突出显示的任何内容,检查第一行是否有注释,如果有,尝试取消所有突出显示的行的注释,如果没有,则向每行添加一层注释字符。这是我所期望的行为;我不只是想让它切换块中的每一行是否被注释,所以在对主题提出多个问题后,它对我来说非常适用。好的。好啊。


    它们中最快速、最直观的方法是重新映射),用于对行进行逐行注释,然后重新映射(,用于逐行注释。试试看,你就不会回去了。

    在Ruby或Bash中,有两个空格缩进:

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

    在C/C++或PHP中,具有4个空间缩进:

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

    缺点是句子移动丢失了()(但das可以在这里填充),并且偶尔会退回到select和replace或ctrlvbkbd来处理长段。但这很罕见。

    对于C-Style,长注释最好处理:

    1
    2
    set cindent
    set formatoptions=tcqr

    …它与使用V[move]gq重新包装单词结合得很好。


    为此,我使用VIM多个光标。

  • 要选择区域,请按0转到要注释的区域第一行或最后一行的第一个字符(它是零,而不是字母"O")。然后按v并使用jk或上下箭头键选择区域。
  • 然后按ctrlxkykbdn,在选择的每一行上放置一个虚拟光标。
  • 然后按iakbd同时编辑所选内容的每一行。

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

    1
    2
    3
    4
    5
    6
    function! CommentToggle()
        execute ':silent! s/\([^ ]\)/\/\/ \1/'
        execute ':silent! s/^\( *\)\/\/ \/\/ /\1/'
    endfunction

    map <F7> :call CommentToggle()<CR>

    它是用于//-注释的,但是您可以很容易地为其他字符调整它。您可以使用autoCmd设置一个领导人,如jqno建议的。

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


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

    按进入视觉模式

    1
    'v'

    然后按

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

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

    1
    'gc'

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

    1
    'gc'

    取消对整个文件的注释:

  • esc退出插入模式
  • gg转到第一行的第一个字符
  • ctrl+vctrl+shift+vbkbd选择当前字符
  • gshift+g转到最后一行
  • 删除所选内容

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

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

    1在每个选定行的文本(空白后)之前插入#。它检查是否已经有#,不插入#两次。也忽略了空行。键2删除一个#。它还保持了对行右侧的评论的安全性。

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

    为了使其正常工作,请将以下行放入您的.vimrc文件中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    " 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 :<C-u>execute b:Comment_ON<CR>
    vnoremap 2 :<C-u>execute b:Comment_OFF<CR>


    我喜欢/* ... */(c-ansi注释),所以这里是我给你的诀窍。当然,您可以将其调整为在不同的情况下使用。

    用/*注释…*/

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

    1
    <c-V>}

    键入要在所选内容中应用的命令

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

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

    详见(i*)。

    取消对/*的注释…*/

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

    1
    <c-V>}

    键入要在所选内容中应用的命令

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

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

    详见(二*)。

    结果

    效果是逐行评论:

    1
    2
    3
    Comment block
    Comment block
    Comment block

    变成(反之亦然):

    1
    2
    3
    /* Comment block */
    /* Comment block */
    /* Comment block */

    最好把它保存为你的.vimrc中的一些map@reg,因为它的类型很多。如果您喜欢单一的/**/而不是整个块,请使用:

    用单个/**/整块注释

    将其保存在登记簿中,例如,用qc记录,然后在段落开头评论:

    1
    v}di/*  */<esc>hhhp

    别忘了再做一次q,完成记录。

    详见(三*)。

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

    把它保存在寄存器中,比如说,@u。将光标放在块内的任意位置,然后:

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

    完成q命令,保存寄存器。

    详见(四*)。

    结果

    效果是多行的单个注释:

    1
    2
    3
    Comment block
    Comment block
    Comment block

    变成(反之亦然):

    1
    2
    3
    /* Comment block
    Comment block
    Comment block */

    解释

    (i*)它通过使用norm来工作,该命令在每个选定的行中重复应用相同的命令。命令只需插入一个/*,找到该行的结尾,然后通过插入一个*/结束。

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

    (ii*)它还使用norm在每一行重复搜索/替换。搜索spaces /* spaces,不替换。在那之后,找到行尾,后面两个字,右一个字母,删去到行尾。

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

    (iii*)按v}选择段落,将其删除,插入注释打开和关闭,移动到中间并粘贴删除的块。

    1
    v}di/*  */<esc>hhhp

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

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

    尽管这个问题已经有了大量的答案,我仍然认为我会对我写的一个小插件大喊大叫:评论。

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

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


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

    上面的代码将注释掉所有包含"spare"的行和一个数字,再加上它将注释发现行的另外两行。有关更多此类用途,请访问:http://vim.wikia.com/wiki/search_and_replace_details


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

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

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


    @CMS的解决方案是最"vim本机"的注释输入/输出行方式。在@cms的第二步中,在ctrlv之后,您还可以使用rykbd 添加注释,或者使用xb删除注释。德鲁·尼尔(DrewNeil)的《实用维姆》(PracticalVim),第46页,很好地解释了这一技巧。

    另一个好的选择是使用一个ex模式命令。:[范围]normalbi 。显然,要用这个来保存击键,您需要注释15+行。


    我个人想要评论A-LA Visual Studio。我在工作中已经习惯了它,以至于它取代了我的肌肉记忆(使用vsvim)。使用shift+v选择所需的行,然后按ctrl+kbakbd、ctrl+c进行注释,或按ctrl+kbakbd、ctrl+u取消注释。

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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的内置commentstring选项中获取注释字符串,如果声明filetype plugin on,则该选项由/usr/share/vim/vim*/ftplugin/*.vim等文件填充。

    1
    2
    3
    4
    filetype plugin on
    autocmd 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

    移除字符和之间的树汁使用此命令注释.c或cpp文件


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

    • noremap ,// :call CommentLine()

    我们可以用行数来称呼它,在视觉模式下,它也可以工作。例如:要注释四行,请使用4,/,要取消注释,请使用4,/。

    取消对行的注释(对于所有语言):

    • noremap ,/ :call UnCommentLine()

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

    Definition of CommentLine()

    function! CommentLine()
    let slash_ft_list = ['c' , 'cpp', 'java', 'scala' , 'systemverilog' , 'verilog' , 'verilog_systemverilog']
    let hash_ft_list = ['sh' , 'ruby' , 'python' , 'csh' , 'conf' , 'fstab' , 'perl']
    let perct_ft_list = ['tex']
    let mail_ft_list = ['mail']
    let quote_ft_list = ['vim']
    if (index(slash_ft_list, &ft) != -1)
    :norm I//
    elseif (index(hash_ft_list, &ft) != -1)
    :norm I#
    elseif (index(perct_ft_list, &ft) != -1)
    :norm I%
    elseif (index(mail_ft_list, &ft) != -1)
    :norm I>
    elseif (index(quote_ft_list, &ft) != -1)
    :norm I"
    endif
    endfunction

    Definition of UnCommentLine()

    function! UnCommentLine()
    let slash_ft_list = ['c' , 'cpp', 'java', 'scala' , 'systemverilog' , 'verilog' , 'verilog_systemverilog']
    let hash_ft_list = ['sh' , 'ruby' , 'python' , 'csh' , 'conf' , 'fstab' , 'perl']
    let perct_ft_list = ['tex']
    let mail_ft_list = ['mail']
    let quote_ft_list = ['vim']
    if (index(slash_ft_list, &ft) != -1)
    :norm ^2x
    elseif (index(hash_ft_list, &ft) != -1)
    :norm ^x
    elseif (index(perct_ft_list, &ft) != -1)
    :norm ^x
    elseif (index(mail_ft_list, &ft) != -1)
    :norm ^x
    elseif (index(quote_ft_list, &ft) != -1)
    :norm ^x
    endif
    endfunction


    有几个VIM插件,如tcomment和nerdcommenter可用。

    我使用tcomment进行评论。

    GCC:它将在当前行上切换注释。v motion gc:它将切换注释一系列可视选定的行。

    示例:v3jgc将切换3行的区域。

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


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

    您可以在中看到这种测试操作的示例http://bknpk.ddns.net/my_web/vim/vim_shell_cmd_on_block.html


    ctrl+v,然后使用选择要注释的行数。然后按shift+iakbd,按_,然后按esc。这将注释掉您选择的行数。

    与取消注释行相反。