我在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(-#)。


当前回答

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

#code code
#code
#code code code

将光标放在左上角的#符号上,然后按CtrlV。这将使您进入视觉块模式。按下向下箭头或J三次以选择所有三条线。然后按D。所有评论都会消失。要撤消,请按U。

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

code code
code
code code code

将光标放在左上角的字符上,按CtrlV。这将使您进入视觉块模式。按↓ 或J三次以选择所有三条线。然后按:

I//Esc键

这是大写的I、//和Escape。

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

其他回答

"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代码块的最优雅方式是什么?并进行了一些小的更改(更改了快捷键,并在#后面添加了空格)。

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

#code code
#code
#code code code

将光标放在左上角的#符号上,然后按CtrlV。这将使您进入视觉块模式。按下向下箭头或J三次以选择所有三条线。然后按D。所有评论都会消失。要撤消,请按U。

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

code code
code
code code code

将光标放在左上角的字符上,按CtrlV。这将使您进入视觉块模式。按↓ 或J三次以选择所有三条线。然后按:

I//Esc键

这是大写的I、//和Escape。

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

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

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

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结束符端函数

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

这里的答案是: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 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。有其他方法可以做到这一点,但对新手(像我)来说,它们更容易混淆。作用Docomment():函数以函数开头,以endfunction结尾。函数必须以大写开头。这个确保此函数使用此版本的Doccomment()覆盖以前定义为Doccomment)的任何函数。没有!,我有错误,但这可能是因为我通过vim命令行定义了新函数。执行“”<,“”>s/^\s*/&'.escape(b:commentChar,'\/')。“/e':Execute调用命令。在这种情况下,我们正在执行替换,它可以取一个范围(默认情况下,这是当前行),例如整个缓冲区的%或突出显示部分的“<,”>^\s*是正则表达式,以匹配一行的开头,后跟任意数量的空格,然后将其附加到(由于&)。这个这里用于字符串连接,因为escape()不能用引号括起来。escape()允许您转义commentChar中与参数(在本例中,\和/)匹配的字符,方法是在它们前面加上\。之后,我们再次用替换字符串的结尾连接,该字符串带有e标志。这个标志让我们无声地失败,这意味着如果我们在给定的行上找不到匹配项,我们就不会对它大喊大叫。作为一个整体,这一行允许我们在第一个文本之前放置一个注释字符,后跟一个空格,这意味我们保持缩进级别。执行“”<,“”>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()返回索引,如果为true,则返回-1。因为if计算所有非零数字为真,所以我们必须比较输出,看看它是否大于-1。vim中的比较如果为false,则返回0,如果为true,则返回1,这就是if希望看到的正确评估结果。vnoremap<silent><C-r>:<C-u>调用Comment()<cr><cr>:vnoremap意味着在视觉模式下映射以下命令,但不要递归映射(意味着不要更改可能以其他方式使用的任何其他命令)。基本上,如果你是一个vim新手,请始终使用noremap来确保你不会破坏东西<silent>的意思是“我不需要你的言语,只需要你的行动”,并且告诉它不要向命令行打印任何内容<C-r>是我们正在映射的对象,在这种情况下是ctrl+r(注意,在正常模式下,使用此映射,您仍然可以正常使用C-r进行“重做”)。C-u有点让人困惑,但基本上它可以确保你不会忘记视觉高亮显示(根据这个答案,它会让你的命令以“<,”>开头,这就是我们想要的)。这里的调用只是告诉vim执行我们命名的函数,<cr>是指点击enter按钮。我们必须点击它一次才能真正调用该函数(否则我们只是在命令行上键入了call function(),我们必须再次点击它以让替代品一直执行(不确定为什么,但无论如何)。

无论如何,希望这能有所帮助。这将接受用v、v或C-v突出显示的任何内容,检查第一行是否有注释,如果有,尝试取消注释所有突出显示的行,如果没有,则为每行添加一层注释字符。这是我想要的行为;我不只是想让它切换块中的每一行是否有评论,所以在问了多个关于这个主题的问题后,它非常适合我。