我在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(-#)。
从这里的答案中的想法开始,我开始了自己的评论功能。它可以打开和关闭评论。它可以处理//打印(“蓝色”)等事情//这个东西是蓝色的,只是切换第一条评论。此外,它在第一个非空白处添加注释和一个空格,而不是在行的开头。另外,在注释和缩进行时,它不会不必要地复制空白,而是使用缩放(: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'
end
endfunction
nnoremap <Leader>t :call ToggleComment()<CR>
inoremap <Leader>t <C-o>:call ToggleComment()<CR>
xnoremap <Leader>t :'<,'>call ToggleComment()<CR>
很好的问题,但没有那么多好的答案。首先,我想说,在这里使用块插入模式不是一个简单的解决方案,只是击键太多,所以显然它必须在选定的行上工作,以提高代码编辑的性能。另一个没人提到的问题是:注释符号应该放在哪里-在行首或实际文本之前?这可能是一个品味问题,但我认为,应该将它放在文本之前,以保持代码可读:当注释符号放在最开始的一行时,它会破坏缩进代码的视觉一致性,因此看起来像一个项目符号列表。考虑到这一点,我最终得到了以下解决方案(我以#comment为例)。在我的vimrc中:
vnoremap 1 :s:^\(\s*\)\([^#\t ]\):\1#\2:e<CR>
vnoremap 2 :s:^\(\s*\)#\(\s*\):\1\2:e<CR>
键1在每个选定行的文本前(空格后)插入#。它检查是否已经有#,而不是两次插入#。并且还忽略空行。键2删除一个#。它还可以确保行右侧的注释安全。
更新:这里是一个示例,说明如何生成依赖于文件类型的切换注释命令。要了解更多信息,请阅读:http://learnvimscriptthehardway.stevelosh.com/chapters/14.html
为了使其正常工作,在.vimrc文件中放入以下行。
" 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>