ChatGPT解决这个技术问题 Extra ChatGPT

在 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 中执行此操作的有效方法是什么?

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

接受的答案应更改为包含如何在不使用插件的情况下完成注释/取消注释块的详细说明的答案之一。 current accepted answer 基本上只是指向第三方插件的链接。
评分最高的答案未提及任何插件,@rationalis 您的评论具有误导性,请您更正或删除它,谢谢。
接受的答案应该是 Magnus answer

E
Eric O Lebigot

对于我大部分时间使用的那些任务block selection

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

注释一块文本几乎是一样的:

首先,转到您要评论的第一行,按 CtrlV。这会将编辑器置于 VISUAL BLOCK 模式。然后使用箭头键选择直到最后一行 现在按 ShiftI,这将使编辑器进入 INSERT 模式,然后按 #。这将在第一行添加一个哈希。然后按 Esc(稍等),它将在所有其他选定的行上插入一个 # 字符。

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

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

https://i.stack.imgur.com/lu6aU.gif

https://i.stack.imgur.com/2Y7eH.gif


默认情况下它是 CTRL+V。 gvim 的 windows 版本使用 Ctrl+Q,因为 Ctrl+V 已经用于粘贴。
你会如何用'//'来做到这一点?
您可以单击 Esc 两次以不等待那一秒;)
这对我不起作用。 Shift-I 进入简单插入模式。
对于 shif-i 不适合他们的人:您应该按 ESC 以查看其他行中粘贴的文本。
S
SO_fix_the_vote_sorting_bug

要在 vim 中注释掉块:

按 Esc(退出编辑或其他模式)

点击 ctrl+v(视觉块模式)

使用 ↑/↓ 箭头键选择您想要的行(它不会突出显示所有内容 - 没关系!)

Shift+i(大写 I)

插入你想要的文本,例如 %

按 EscEsc

要在 vim 中取消注释块:

按 Esc(退出编辑或其他模式)

点击 ctrl+v(视觉块模式)

使用 ↑/↓ 箭头键选择要取消注释的行。如果要选择多个字符,请使用一种或组合以下方法: 使用左/右箭头键选择更多文本 选择文本块 使用 shift + ←/→ 箭头键 您可以重复按下下面的删除键,如常规删除按钮

使用左/右箭头键选择更多文本

选择文本块使用 shift + ←/→ 箭头键

您可以重复按下下面的删除键,就像常规删除按钮一样

按 d 或 x 删除字符,必要时重复


@amelia:评论快捷方式对我不起作用。 Shift + i 带我进入插入模式。它取决于vim版本吗?
为什么需要一秒钟?
我对这个答案的唯一问题是它告诉你使用箭头键。
改为按 Esc 两次。 :)
起初启用评论对我不起作用,但在阅读后再次正常工作:1.确保您使用 Ctrl-V,而不是 V 进行选择 2.插入时它会出现,因为您只修改了一行 3.当您最后按 Esc 时,所有插入都会发生
M
Magnus

有时我被困在一个远程盒子里,我的插件和.vimrc 无法帮助我,或者有时NerdCommenter 弄错了(例如嵌入在HTML 中的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 然后按转义键(或者更简单,只需录制一个快速宏,然后使用 norm 在每一行上执行该宏)。

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

vnoremap <C-n> :norm

注意 3:Bare-bones vim 有时没有将 norm 命令编译到其中,因此请务必使用增强版本,即通常是 /usr/bin/vim,而不是 /bin /vi

(感谢@Manbroski 和@rakslice 对这个答案的改进)


@Shyam ctrl-v 技术与特殊的仅块选择命令相结合是大多数其他答案所推荐的;但是我个人发现我所描述的“规范”技术更容易,因为它除了规范命令本身之外没有引入任何新语法,所以我可以重用我已经知道的关于 vim 的知识。
要取消注释缩进块,说 :norm ^x 很有用。这种方法通常具有处理区域选择的优点(例如 vi{ 将选择大括号内)。此类 文本对象选择器 不适用于 Visual Block
啊,我刚刚弄明白了——在 centos 6 上,/bin/vi 是 vim 7.2,但它与 /usr/bin/vim 的构建不同,而且它关闭了这样的功能。
这是迄今为止最好的答案。尤其是与 vip 结合以选择整个段落时。
这太棒了。我是一个 AVID 宏用户。我为我将不得不重复一次的击键动态创建宏(通常是递归的)。我现在只考虑宏。我从来不知道:normal。我要好好利用它。
B
Bhargav Rao

我使用 NERD Commenter script。它使您可以轻松地在代码中注释、取消注释或切换注释。

comments 中所述:

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


有趣的!我阅读了文档,发现有一个“性感评论”——只需使用“\cs”。对于 Ruby,它将使用 =begin=end 来注释多行而不是哈希标记。
我认为这不是使用 vim 的最快方法,因为它需要安装插件。最佳答案也已获得更多投票,但尚未标记为解决方案。
不要停在这里。大多数投票的答案都在下面,不需要任何插件。 stackoverflow.com/a/15588798/2117868stackoverflow.com/a/1676690/2117868
@whirmill我认为“最好”真的取决于用例。如果我想在我的生活中切换一次评论,可视块模式会更快。但是,如果我不介意安装插件并且希望尽可能少地击键来切换评论并且不必区分添加或删除评论之间的操作 - 那么这可能是“最佳答案”。
@whirmill 好点。尽管我可以争辩说“最快”也可能有多种解释。虽然你的会更常见/可能。 :)
B
Bruno Bronosky

我的 .vimrc 中有以下内容:

" Commenting blocks of code.
augroup commenting_blocks_of_code
  autocmd!
  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 END
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 来取消注释(在正常模式和可视模式下都有效)。

(我多年前从某个网站上偷了它,所以我无法完全解释它是如何工作的 :)。有一个 comment 来解释它。)


我应该使用什么快捷方式?我不能完全从 vim 代码本身确定!
在普通或可视模式下,使用“,cc”(3 个字符序列)注释当前行,使用“,cu”取消注释当前行。
我喜欢 :)!谢谢!在旁注中,我不觉得很难解释。 a)它重新映射一个命令(非递归[见这个](stackoverflow.com/questions/3776117/…)所以现在当你按下时,cc :... 事情被执行。b)现在这基本上是一个 sed(s/what/towhat/where ) 命令根据您打开的文件类型将 ^ (行首)更改为正确设置的注释字符 c) 至于无声的东西,它们只是抑制命令的输出。 d):nohlsearch 阻止它突出显示 sed 搜索
请注意,这不是加载自动命令的正确方法。它们应该在一个 augroup 中,否则它们将被多次添加到 vim 并导致很多减速。请参阅:learnvimscriptthehardway.stevelosh.com/chapters/14.html。我已经添加了对这个问题的回答。
我的模组默认为 // 对于未列出的文件类型并使用 <Leader>(默认 \ )而不是 , 并在任何缩进后添加/删除注释字符:gist.github.com/zonidjan/7fc11c2e9574c84383a87a8fcbe4b1ca
J
JonnyRaa

指定要在 vim 中注释的行:

显示行号:

:set number

然后

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

或这个:

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

由于您只是更改每行的第一个字符,因此您不需要最后的“g”
嵌入式盒子上的一些vim(如openwrt)没有可视模式..所以这太棒了:)
你能解释一下为什么 :%s/^/#/g 会注释掉所有行吗?我想知道百分号 %
要取消注释这些行,您可以编写:5,17s/^#/
伟大的!它非常适用于块选择,例如:va{var 用于 ruby。
i
isomorphismes

这是我的做法:

转到要注释掉的第一行的第一个字符。在 GVIM 中按 Ctrl+q 或在 VIM 中按 Ctrl+v,然后向下选择要注释掉的行上的第一个字符。然后按 c,并添加注释字符。

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


c 也删除第一个字符。 CMS 的答案是正确的,即按 I 然后输入注释字符,然后输入 Esc (这是在 windows vim 上)
这有效,除了需要在第三步按下“r”,而不是“c”。
或者,您可以在按 c 后按 ESC 两次,这应该可以解决问题
所有这些选项都会破坏行中的第一个字符。
F
Flavio Wuensche

切换评论

如果您只需要切换评论,我宁愿在 tpope 之前使用 commentary.vim

https://i.stack.imgur.com/NYiEh.gif

安装

病原:

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

vim 插件:

Plug 'tpope/vim-commentary'

包装:

Plugin 'tpope/vim-commentary'

进一步定制

将此添加到您的 .vimrc 文件中:noremap <leader>/ :Commentary<cr>

您现在可以通过按 Leader+/ 来切换评论,就像 Sublime 和 Atom 一样。


谢谢!将来某个时候会支持在 html 中进行 css 评论吗?
但有时您不想使用插件使服务器膨胀。
对我来说,这是最好的解决方案。我已经有了。插件已安装但忘记实现键绑定。现在就像一个魅力!
不错,谢谢!这就是我为普通模式和插入模式使用 C-/ 自定义行注释的方式:nnoremap <C-_> :Commentary<cr>jinoremap <C-_> <Esc>:Commentary<cr>ji。我不知道原因,但 vim 将 / 识别为 _,这就是我使用 C-_ 的原因。
这真的很有用。
i
ideasman42

我想出了一个简单的添加到我的 .vimrc 文件中,它工作得很好并且可以很容易地扩展。您只需将新的文件类型添加到 comment_map 及其评论前导。

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

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 静态函数/映射更减慢 Vim 的启动速度,但这只是我的偏好。我也试图让它保持简单和高效。如果您确实使用自动命令,则需要确保将它们放在自动命令组中,否则回调会在每个文件加载时多次添加到文件类型中,并导致大量性能下降。


我对 vim 完全陌生,我应该按什么按钮来切换映射功能?底部的 <leader><Space> 声明是什么?
您可以用 <,> 之类的键替换 。然后按 ,SPACE ,它将切换该行的注释状态。领导者是你的领导者,Vim 的默认 是 \,但你可以设置你自己的,比如 "let mapleader = ','"
很好的答案,虽然有一个烦恼,评论已经有一些评论的块,会将评论交换为未评论的行。 QtCreator for eg 仅在所有非空行都有前导注释时删除注释,否则添加前导注释。
我使用 \zs\ze 正则表达式技巧制作了一个略有不同的版本,代码变得更小了。你可以看到它here
这是我使用的方法。如果您在旧版本的 vim 上运行它,您可能需要删除代码行中的任何尾随空格以使其正常工作。我使用 <C-_> 来匹配 Control-/ 以匹配大多数其他行注释键绑定。
R
R. Martinho Fernandes

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


A
Andy

我使用 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


i
innaM

这是我的 .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 删除评论。


这对于初学者如何学习编写自己的 .vimrc 非常有帮助。
map 涵盖正常和可视模式,因此您不需要 vmap
更好的地方是在 after/ftplugin/ruby.vim
也使用 <leader>ic<leader>rc
M
Markus Dutschke

我结合了 Phil 和 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/\([^ ]\)/' . escape(b:comment_leader,'\/') . ' \1/'
    execute ':silent! s/^\( *\)' . escape(b:comment_leader,'\/') . ' \?' . escape(b:comment_leader,'\/') . ' \?/\1/'
endfunction
map <F7> :call CommentToggle()<CR>

这个怎么运作:

假设我们使用#-comments。

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

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

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


Y
Yugandhar Chaudhari

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

没有任何插件的最简单的是

选择块 - V 然后 j 或 k 或任何相关动作(不要使用箭头键):) 然后点击:它提示命令:'<,'> 使用 # - `s/^/#/` 使用 ` 来评论//` - `s/^/\/\//` 使用 # 取消注释 - `s/^#//` 使用 `//` - `s/^\/\//`

解释——

'<,'> - 应用于视觉块

s - 替代

^ - 以

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

更新

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

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

将其粘贴到 .vimrc

function CommentUncomment()
  let line = getline('.')
  if line[:1] == "//"
      norm ^2x
  else 
      norm I//
  endif
endfunction

nnoremap <Space><Space> :call CommentUncomment()<CR>

这是我发现的最简单的方法。在这种情况下,插入命令的完整命令将是 '<,'>s/^/#/g。对我来说,如果不添加 /g at the end, which indicates the cursor to move at the end of the '<,'>` 范围就行不通
如果您启用了数字行,您可以这样做::1,10 s/^/#/ 注释第 1 到 10 行。
无需转义斜线,只需使用不同的分隔符::s#^#//
u
uckelman

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


真的应该是:n,ms/^\s.#// 因为你可能有前导空格并且可能没有在散列后面加上一个
i
imagineerThat

前面有 30 个答案,我将尝试提供一个更简单的解决方案:在行首插入一个 #。然后下一行并按点 (.)。要重复,请执行 j.j. 等...要取消注释,请删除 #(您可以在 # 上点击 x),然后执行相反的操作使用 k. 等...


这是一个非常简单的答案,即使是初学者也能理解和使用。但是,它在要评论的大量行上工作得非常缓慢。要解决这个问题,您可以将 I#<Esc>j 写入缓冲区 - 例如 c - 然后执行 10@c,或者任何适合您的行数。
对于这样简单的任务,非常麻烦的组合键 :( 我经常使用 cmd+/ 来评论和取消评论,而缺少内置的功能是我不使用 vim 进行严肃工作的原因
K
K.Dᴀᴠɪs

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

#code code
#code
#code code code

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

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

code code
code
code code code

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

我//Esc

那是大写字母 I、// 和 Escape。

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


如果您错过了“左上角”哈希,您可以按 o 以在可视模式下将光标移动到“另一边”。
我认为这是最好的使用。不需要任何第三方,只需使用本机 vim
最佳答案,简单且没有任何第三方
R
Rick

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

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


R
Rich

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

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

这种方法可以让您执行以下操作:

ccj 注释下两行,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: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

修改上面的正则表达式以适应您对 # 的位置的喜好:


“全新的 [...] 动作”似乎有点过头了:t_comment 和 vim-commentary 插件,它们都早于这个答案,允许您使用动作注释掉。
好东西!赞成。 (我也想我可能会开始使用这种方法而不是我以前使用的插件,所以感谢您编写它!)
f
fugu

tpope 有一个名为 vim-commentary 的改变生活的插件

https://github.com/tpope/vim-commentary

该插件提供:

理智

正确缩进的注释

不注释掉空/不必要的行

用法:

通过 Vundle(我猜是 Pathogen)安装。

突出显示您的文本并按 : 将显示为 :<,'>

在此处输入 Commentary :<,'>Commentary 并按 Enter。

繁荣。你完成的芽。


vim-commentary(就像所有 tpope 的插件一样)具有惯用 vim 的优势。 gc = “去评论”,gcap = “去评论一段”,等等。
这可能只是吉姆·斯图尔特对蒂姆·波普回答的编辑吗?
S
SDGator

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


p
pylang

一些常规的 Vim 命令不适用于我在 Windows 上的设置。 Ctrl + v 和 Ctrl + q 是其中的一部分。后来我发现以下方法可以取消注释行。

给定

一些缩进的注释

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

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

方法

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

视觉块模式(更快)

Ctrl + Shift + v 进入可视块模式

js选择垂直线。

l 包括水平字符(可选)

x 删除块

搜索/替换 + 正则表达式

选择具有常规视觉模式的文本,即 Shift + v

类型 :。你会得到这个提示符'<,'>。

键入正则表达式,例如 s/#// 将散列替换为空。 (可选:键入 s/# // 以包含空格)。

进入

:norm 命令

选择具有常规视觉模式的文本,即 Shift + v

类型 :。你会得到这个提示符'<,'>。

发出命令。键入 :norm ^x 以删除第一个非空白字符和下一个字符。 (可选:如果没有缩进,请尝试 :norm x 或 :norm ^xx 以包含空格)。

进入

g 模式

选择具有常规视觉模式的文本,即 Shift + v

类型 :。你会得到这个提示符'<,'>。

发出命令。输入 g/#/norm! ^ x。 (可选:输入 g/#/norm!^xx 以包含空格)。

进入

结果

    Practice in Vim
    Practice in Vim
    Practice in Vim
    Practice in Vim
    Practice in Vim
    Practice in Vim
    Practice in Vim

也可以看看

发布删除缩进评论

发布如何使用 Vim 快速评论

ThePrimeagen 的 g 命令教程。

VimTrick 关于注释代码的教程


q
qba

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

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

j
jeremysprofile

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

这个答案是为了 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() :函数以 function 开头并以 endfunction 结尾来声明。函数必须以大写字母开头。这 !确保此函数使用此版本的 Docomment() 覆盖任何先前定义为 Docomment() 的函数。如果没有 !,我会出错,但这可能是因为我通过 vim 命令行定义了新函数。

执行 '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e' :执行调用命令。在这种情况下,我们正在执行替换,它可以采用一个范围(默认情况下这是当前行),例如整个缓冲区的 % 或突出显示部分的 '<,'>。 ^\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 中的比较如果为假则返回 0,如果为真则返回 1,这就是如果希望看到正确评估的结果。

vnoremap :call Comment() : vnoremap 表示在可视模式下映射以下命令,但不要递归映射它(意思是不要更改任何其他可能以其他方式使用)。基本上,如果您是 vim 新手,请始终使用 noremap 来确保您不会破坏任何东西。 的意思是“我不想要你的话,只想要你的行动”,并告诉它不要在命令行中打印任何内容。 是我们正在映射的东西,在这种情况下是 ctrl+r(请注意,您仍然可以使用 Cr 在正常模式下通过此映射正常“重做”)。 Cu 有点令人困惑,但基本上它确保你不会忘记你的视觉突出显示(根据这个答案,它使你的命令以我们想要的 '<,'> 开头)。这里的 call 只是告诉 vim 执行我们命名的函数,而 是指点击 enter 按钮。我们必须点击一次才能真正调用该函数(否则我们只是在命令行上输入了 call function() ,我们必须再次点击它才能让我们的替代品一直通过(不太清楚为什么,但是无所谓)。

无论如何,希望这会有所帮助。这将采用 vVC-v 突出显示的任何内容,检查第一行是否已注释,如果是,请尝试取消注释所有突出显示的行,如果没有,则为每行添加一层额外的注释字符线。这是我想要的行为;我不只是希望它切换块中的每一行是否被评论,所以它对我来说非常适合在关于该主题的 asking multiple 个问题之后。


C
Community
"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 行。

我从 What's the most elegant way of commenting / uncommenting blocks of ruby code in Vim? 上的人那里得到了原始代码并做了一些小改动(更改了快捷键,并在 # 后添加了一个空格)。


J
Jim Stewart

我使用 Tim Pope 的 vim-commentary 插件。


K
Kingsley Ijomah

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

按 进入可视模式

'v'

然后按

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

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

'gc'

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

'gc'

P
Phil

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

function! CommentToggle()
    execute ':silent! s/\([^ ]\)/\/\/ \1/'
    execute ':silent! s/^\( *\)\/\/ \/\/ /\1/'
endfunction

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

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

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


这很漂亮,也适用于 V 的多个选定行
n
nrz

为此,我使用 vim-multiple-cursors

要选择区域,请通过按 0 转到要注释掉的区域的第一行或最后一行的第一个字符(它是零,而不是字母“o”)。然后按 V 并使用 J、K 或上下箭头键选择区域。然后按 CtrlN 将虚拟光标放在所选内容的每一行上。然后按 I 同时编辑选择的每一行。


它在这里不起作用,当我按 Ctrl + N 时,它会选择下面的行。
@Gerep 您安装了 vim-multiple-cursors 吗?如果是,你有最新版本的 vim-multiple-cursors 吗?您是否通过按 0 移动到要注释掉/取消注释的第一行或最后一行的第一个字符?然后您是否使用可视模式选择了要注释掉/取消注释的行(按 VCtrl+V 进入可视模式,然后按 JK 选择您想要的所有行在按下 Ctrl+N 之前注释掉/取消注释)?
哦!!!真的很抱歉,我以为 vim-multiple-cursors 是内置功能,现在可以使用了,谢谢 =)
只为我工作:<C-v>\d<cr><C-n>i#<cr>。谢谢你的建议。
b
bgran

这是基于上述 C-v 后接 I 方法的基本单行代码。

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

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

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

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

1
2

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

//1
//2