我在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

假设我想取消注释第一个定义中的所有行。。。端部。在Vim中有什么有效的方法可以做到这一点?

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


当前回答

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

您可以在http://bknpk.ddns.net/my_web/VIM/vim_shell_cmd_on_block.html

其他回答

这是一个基于C-v的基本单线图,然后是上面概述的I方法。

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

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

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

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

1
2

然后运行this::Comment//,结果将是:

//1
//2

我个人不喜欢注释“切换”功能,因为它会破坏代码中已经包含的注释。此外,我希望注释字符始终显示在最左边,这样我可以很容易地看到注释块。此外,我希望这是嵌套的(如果我首先注释掉一个块,然后是一个封闭块)。因此,我稍微改变了其中一个解决方案。我使用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>

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

noremap<silent>,//:调用CommentLine()<CR>

我们可以用许多行来调用它,在视觉模式下也可以。Like:要注释四行,请使用4,//,要取消注释,请使用5,/。

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

noremap<silent>,/:调用UnCommentLine()<CR>

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

CommentLine()的定义

作用注释行()让slash_ft_list=['c','cpp','java','scala','systemverilog','verilog'、'verilog_systemverilog']让hash_ft_list=[sh','ruby','python','csh','sconf','fstab','perl']让perct_ft_list=['tex']让mail_ft_list=['mail']让quote_ft_list=['vim']如果(索引(slash_ft_list,&ft)!=-1):规范I//elseif(索引(hash_ft_list,&ft)!=-1):规范I#elseif(索引(perct_ft_list,&ft)!=-1):标准I%elseif(索引(mail_ft_list,&ft)!=-1):规范I>elseif(索引(quote_ft_list,&ft)!=-1):规范I“结束符端函数

UnCommentLine()的定义

作用取消注释行()让slash_ft_list=['c','cpp','java','scala','systemverilog','verilog'、'verilog_systemverilog']让hash_ft_list=[sh','ruby','python','csh','sconf','fstab','perl']让perct_ft_list=['tex']让mail_ft_list=['mail']让quote_ft_list=['vim']如果(索引(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):标准^x结束符端函数

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

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>"

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