本文共 15597 字,大约阅读时间需要 51 分钟。
我在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 endend
假设我想取消注释第一个def ... end
部分中的所有行。 在中这样做的有效方法是什么?
一般来说,我正在寻找一种简单流畅的方式来评论和取消注释。 在这里,我正在处理Ruby代码,但它可能是JavaScript( //
)或Haml( -#
)。
这个简单的片段来自我的.vimrc:
function! CommentToggle() execute ':silent! s/\([^ ]\)/\/\/ \1/' execute ':silent! s/^\( *\)\/\/ \/\/ /\1/'endfunctionmap:call CommentToggle()
它适用于// - 评论,但您可以轻松地适应其他角色。 您可以使用autocmd将领导者设置为jqno建议。
这是一种非常简单有效的方式,可以自然地使用范围和视觉模式。
%
如果要选择多个字符,请使用一个或组合这些方法:
如果你已经知道了行号,那么n,ms/# //
就行了。
这是我的.vimrc
:
"insert and remove in visual and normal modevmap ,ic :s/^/#/g:let @/ = "" map ,ic :s/^/#/g :let @/ = "" vmap ,rc :s/^#//g :let @/ = "" map ,rc :s/^#//g :let @/ = ""
在正常和可视模式下,这让我按,ic插入注释,和rc删除注释。
使用Control-V选择文本的矩形:转到第一个#
字符,键入Ctrl + V ,向右移动一次,然后向下移动,直到注释结束。 现在输入x
:你要删除所有#
字符后跟一个空格。
我是这样做的:
转到要注释掉的第一行的第一个字符。
在GVIM中按Ctrl + q或在VIM中按Ctrl + v ,然后向下选择要注释掉的行上的第一个字符。
然后按c ,添加注释字符。
取消注释以相同的方式工作,只需键入空格而不是注释字符。
我的.vimrc
有以下内容:
" 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,cc : silent s/^/ =escape(b:comment_leader,'\/') / :nohlsearch noremap ,cu : silent s/^\V =escape(b:comment_leader,'\/') //e :nohlsearch
现在你可以输入,cc
来评论一行,cu
取消注释一行(在普通模式和可视模式下都可以)。
(我多年前从某个网站偷了它,所以我不能完全解释它是如何工作的:)。 有一个说明。)
对于那些任务,我使用大部分时间 。
将光标放在第一个#
字符上,按Ctrl V (或Ctrl Q表示gVim),然后向下直到最后一个注释行并按x ,这将垂直删除所有#
字符。
对于评论文本块几乎是相同的:
VISUAL BLOCK
模式。 INSERT
模式,然后按# 。 这将向第一行添加哈希。 #
字符。 对于debian / ubuntu默认附带的精简版vim,请在第三步中键入: s/^/#
。
这是两个用于视觉参考的小屏幕录音。
评论:
取消注释:
我喜欢使用tcomment插件: : script_id = 1173
我已经映射了gc和gcc来评论一行或突出显示的代码块。 它检测文件类型并且工作得很好。
我使用 。 它可以让您轻松评论,取消注释或切换代码中的注释。
如中所述:
对于任何对使用感到困惑的人,默认的领导者是“\\”所以10 \\ cc将评论十行,10 \\ cu将取消注释这十行
我使用 。 它评论我需要的一切(编程语言,脚本,配置文件)。 我使用它与视觉模式绑定。 只需选择要评论的文本,然后按co / cc / cd即可。
vmap co :call EnhancedCommentify('','guess')vmap cc :call EnhancedCommentify('','comment') vmap cd :call EnhancedCommentify('','decomment')
我标记了第一行和最后一行(ma和mb),然后执行:'a,'bs / ^#//
我使用 (在vim.org上找到),
它适用于C,C ++,Java,PHP [2345],proc,CSS,HTML,htm,XML,XHTML,vim,vimrc,SQL,sh,ksh,csh,Perl,tex,fortran,ml,caml,ocaml, vhdl,haskel和普通文件
它在普通模式和可视模式下对不同源文件中的行进行注释和取消注释
用法:
指定要在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
将光标放在左上角的#
符号上,然后按Ctrl V. 这使您处于可视阻止模式。 按向下箭头或J三次以选择所有三条线。 然后按D键。 所有评论都消失了。 要撤消,请按U.
如何在vi中评论以下三行:
code codecodecode code code
将光标放在左上角的字符上,按Ctrl V. 这使您处于可视阻止模式。 按↓或J三次以选择所有三条线。 然后按:
我 / / Esc
这是资本I,//和Escape。
按ESC键时,所有选定的行都将获得您指定的注释符号。
我使用Tim Pope的插件。
我结合了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/\([^ ]\)/' . b:comment_leader . ' \1/' execute ':silent! s/^\( *\)' . b:comment_leader . ' \?' . b:comment_leader . ' \?/\1/'endfunctionmap:call CommentToggle()
有时候我被绑在一个远程盒子里,我的插件和.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-char注释,那么我只需执行:norm xx
删除两个字符。
如果评论在OP的问题中缩进,那么您可以锚定您的删除,如下所示:
:norm ^x
这意味着“转到第一个非空格字符,然后删除一个字符”。 请注意,与块选择不同,即使注释具有不均匀的缩进,此技术也可以工作!
注意 :由于norm
实际上只是执行常规vim命令,因此您不仅限于注释,还可以对每一行进行一些复杂的编辑。 如果您需要将转义字符作为命令序列的一部分,请键入ctrl-v然后点击转义键(或者更简单,只需记录一个快速宏,然后使用norm在每一行上执行该宏)。
注意2 :如果你发现自己经常使用norm
你当然也可以添加一个映射。 例如,在〜/ .vimrc中放入以下行可让您在进行视觉选择后键入ctrl-n
而不是:norm
vnoremap:norm
注3 :Bare-bones vim有时没有编译成norm
命令,所以一定要使用增强版本,即通常是/ usr / bin / vim,而不是/ bin / vi
(感谢@Manbroski和@rakslice对此答案的改进)
我已经提出了一个简单的添加到我的.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" endendfunctionnnoremap:call ToggleComment() vnoremap :call ToggleComment()
注意:
我没有对文件类型/加载使用任何回调或挂钩,因为我发现它们比.vimrc
静态函数/映射更慢地减慢了Vim的启动速度,但这只是我的偏好。 我也试图保持简单和高效。 如果您确实使用自动命令,则需要确保将它们放在自动命令组中,否则回调会在每个文件加载时多次添加到文件类型,并导致大量性能下降。
从这里的答案中的想法开始,我开始自己的评论功能。 它会打开和关闭评论。 它可以处理//print('blue'); //this thing is blue
//print('blue'); //this thing is blue
,只是切换第一个评论。 此外,它添加了注释和单个空格,就在第一个非空白区域而不是行的最开头。 另外,它不会不必要地复制空白,但是在评论和缩进行时使用缩放(:h \\ zs求助)来避免这种额外的工作。 希望它有助于一些极简主义者。 欢迎提出建议。
" 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' endendfunctionnnoremapt :call ToggleComment() inoremap t :call ToggleComment() xnoremap t :'<,'>call ToggleComment()
最快和他们所有的最直观的方法是重新映射)
为线步行下注释,然后(
以进行现场-取消注释。试试吧,你不回去了。
在Ruby或Bash中 ,使用2空格缩进:
map ) I#jmap ( k^2x
在C / C ++或PHP中 ,带有4个空格的缩进:
map ) I//jmap ( k^4x
缺点是,你失去(
和)
句子运动(但das
可以在那里填写),你会偶尔依傍选择和替换或Ctrl V代表处理长段。 但这非常罕见。
对于C风格,长评论最好用以下方式处理:
set cindentset formatoptions=tcqr
...结合使用V[move]gq
来重做自动换行。
您可以使用tpope( )的vim-comment,您可以按如下方式使用它:
按下进入可视模式
'v'
然后按
'j' repeatedly or e.g 4j to select 4 row
现在您只需输入键即可完成选择:
'gc'
这将注释掉所有选择,取消注释重复键:
'gc'
我喜欢/* ... */
(C ansi评论),所以这里是我的诀窍。 当然,您可以将其调整为在不同情况下使用。
评论/ * ... * /
选择文本(转到开始,启动视觉块,跳转}
:
}
在选择中键入要应用的命令
:norm i/*$a */
命令看起来像:: :'<,'>norm i /* ^[$a */
有关详细信息,请参阅(i *)。
取消注释/ * ... * /
选择文本(如前所述,或您喜欢的其他方式):
}
在选择中键入要应用的命令
:norm :s-\s*/\*\s*-$bbld$
命令看起来像:: :'<,'>norm :s-\\s*/\\*\\s*-^M$bbld$
有关详细信息,请参阅(ii *)。
结果
效果是逐行评论:
Comment blockComment blockComment block
成为(反之亦然):
/* Comment block *//* Comment block *//* Comment block */
最好将它保存为.vimrc
某些map
或@reg
,因为键入的内容很多。 如果您更喜欢整个块的单个/*
和*/
,请使用:
使用单个/ * * /整个块进行注释
将其保存在寄存器中,然后记录qc
,然后在段落的开头进行注释:
v}di/* */hhhp
并且不要再忘记q
,完成记录。
有关详细信息,请参阅(iii *)。
从块中取消注释单个/ * * /
保存在注册表中,比如说@u
。 将光标放在块内的任何位置,并且:
?/\*xx/\*/ xx
通过完成q
命令保存寄存器。
有关详细信息,请参阅(iv *)。
结果
效果是多行的单个注释:
Comment blockComment blockComment block
成为(反之亦然):
/* Comment blockComment blockComment block */
说明
(i *)它使用norm
,它在每个选定的行中重复应用相同的命令。 该命令只需插入一个/*
,找到该行的结尾并通过插入*/
:norm i/*$a */
(ii *)它还使用norm
在每一行重复搜索/替换。 搜索spaces /* spaces
并替换为spaces /* spaces
。 在那之后,找到行尾,后面两个单词,右边一个字母,删除到最后。
:norm :s-\s*/\*\s*-$bbld$
(iii *)通过v}
选择段落,删除它,插入注释打开和关闭,移动到中间并粘贴已删除的块。
v}di/* */hhhp
(iv *)在中间的任何地方,向后找a /*
,删除它; 发现转发*/
,删除它。
?/\*xx/\*/ xx
是的,这个问题已经有33个(主要是重复的)答案。
这是另一种如何在Vim中评论线条的方法: 运动 。 基本思想是通过键入yip
或通过键入dj
删除2行来使用与删除段落相同的方法来注释或取消注释行。
这种方法可以让你做到这样的事情:
ccj
评论未来2线出来, cuk
它们注释掉;
cci{
评论一个区块,并且cui{
取消注释;
ccip
将整个段落评论出来,然后cuip
其取消注释。
ccG
将所有内容评论到最后一行,然后cugg
取消注释到第一行的所有内容。
您只需要2个在运动中运行的功能,以及每个功能的2个映射。 首先,映射:
nnoremapcc :set opfunc=CommentOut g@vnoremap cc : call CommentOut(visualmode(), 1) nnoremap cu :set opfunc=Uncomment g@vnoremap cu : call Uncomment(visualmode(), 1)
(请参阅有关g@
运算符和operatorfunc
变量的手册。)
而现在的功能:
function! CommentOut(type, ...) if a:0 silent exe "normal! :'<,'>s/^/#/\`<" else silent exe "normal! :'[,']s/^/#/\ '[" endifendfunctionfunction! Uncomment(type, ...) if a:0 silent exe "normal! :'<,'>s/^\\(\\s*\\)#/\\1/\ `<" else silent exe "normal! :'[,']s/^\\(\\s*\\)#/\\1/\ `[" endifendfunction
修改上面的正则表达式,以满足您对#
应该在哪里的品味:
在我之前有30个答案,我将尝试提供一个更简单的解决方案:在行的开头插入一个#
。 然后沿着一条线按下( .
)。 重复,做j
, .
, j
, .
等等...要取消注释,删除#
(你可以在#
点击x
),然后使用k
,反向执行.
,等等...
如果你需要的只是切换评论,我宁愿和一起去 。
病原:
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一样。
这个改变生命的插件由tpope
称为vim-commentary
tpope
这个插件提供 :
用法 :
:<,'>
:<,'>Commentary
并按Enter键 。 这是一个基于Cv
的基本Cv
后面是I
概述的I
方法。
此命令( :Comment
)将选定的字符串添加到任何选定行的开头。
command! -range -nargs=1 Comment :execute "'<,'>normal!0I" . . " "
将此行添加到.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 grabbed execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'endfunctionfunction! Uncomment () "uncomment on all our lines execute '''<,''>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 match if match(getline(l:line), '^\s*'.b:commentChar)>-1 call Uncomment() else call Docomment() endifendfunctionvnoremap: call Comment()
这个怎么运作:
let b:commentChar='//'
:这会在vim中创建一个变量。 这里的b
指的是范围,在这种情况下包含在缓冲区中,意味着当前打开的文件。 您的注释字符是字符串,需要用引号括起来,引号不是切换注释时要替换的内容的一部分。
autocmd BufNewFile,BufReadPost *...
:自动命令触发不同的东西,在这种情况下,这些是在新文件或读取文件以某个扩展名结束时触发。 触发后,执行以下命令,允许我们根据文件类型更改commentChar
。 还有其他方法可以做到这一点,但它们对新手(比如我)更容易混淆。
function! Docomment()
function! Docomment()
:函数通过以function
开头并以endfunction
结尾来声明。 功能必须以资本开头。 的!
确保此函数使用此版本的Docomment()
覆盖任何定义为Docomment()
先前函数。 没有!
,我有错误,但那可能是因为我通过vim命令行定义了新功能。
execute '''<,''>s/^\\s*/&'.escape(b:commentChar, '\\/').' /e'
execute '''<,''>s/^\\s*/&'.escape(b:commentChar, '\\/').' /e'
:执行调用命令。 在这种情况下,我们正在执行substitute
,它可以取一个范围(默认情况下这是当前行),例如整个缓冲区的%
或突出显示的部分的'<,'>
。 ^\\s*
是正则表达式,用于匹配行的开头,后跟任意数量的空格,然后附加到(由于&
)。 的.
这里用于字符串连接,因为escape()
不能用引号括起来。 escape()
允许你在commentChar
中转义匹配参数(在本例中为\\
和/
)的字符,方法是在它们前加上\\
。 在此之后,我们再次与我们的substitute
字符串的结尾连接,该字符串具有e
标志。 这个标志让我们无声地失败,这意味着如果我们在给定的行上找不到匹配项,我们就不会对此大喊大叫。 总的来说,这一行让我们在第一个文本之前放置一个注释字符后跟一个空格,这意味着我们保持缩进级别。
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为true的索引,如果未找到匹配则返回-1
。 因为if
所有非零数字评估为真,我们必须比较输出以查看它是否大于-1。 vim
比较如果为false则返回0,如果为true则返回1, if
想要正确评估if
返回0。
vnoremap <silent> <Cr> :<Cu>call Comment()<cr><cr>
: vnoremap
意味着在可视模式下映射以下命令,但不要递归映射它(意味着不要更改任何其他命令以其他方式使用)。 基本上,如果你是一个vim新手,总是使用noremap
来确保你不会破坏东西。 <silent>
表示“我不想要你的话,只是你的行为”,并告诉它不要在命令行中打印任何内容。 <Cr>
是我们要映射的东西,在这种情况下是ctrl + r(请注意,在正常模式下,通过此映射,您仍然可以正常使用Cr作为“redo”)。 Cu
有点令人困惑,但基本上它确保你不会忘记你的视觉突出显示(根据它会让你的命令以'<,'>
开始,这就是我们想要的)。 这里call
只是告诉vim执行我们命名的函数, <cr>
指的是按下enter
按钮。 我们必须打一次实际调用函数(否则我们只是在命令行上键入call function()
,我们必须再次点击它以让我们的替代品一直通过(不确定为什么,但是无所谓)。
无论如何,希望这会有所帮助。 这将采用v
, V
或Cv
突出显示的任何内容,检查第一行是否被注释,如果是,则尝试取消注释所有突出显示的行,如果没有,则为每行添加额外的注释字符层。 这是我理想的行为; 我不仅仅想让它切换块中的每一行是否被评论,所以在关于这个主题的问题后,它对我来说非常适合。
转载地址:http://oxogj.baihongyu.com/