部分用于练习,部分用于个人用途,我希望能够进入视觉模式,选择一些线条,然后点击“,”然后切换评论。 (我知道NerdCommenter存在,但我想要一些简单而没有任何想象力的东西 - 而且,这也是实践。)
我了解到你可以通过'& filetype'来访问文件类型,并且'''。连接字符串,==#是区分大小写的字符串比较,=〜是正则表达式匹配。我还了解到getline('。')获取了视觉模式突出显示的行(如果突出显示多行,则为每行)。
这是我的(有缺陷的)
vnoremap , :call ToggleComment()<CR>
function! ToggleComment()
"Choose comment string based on filetype.
let comment_string = ''
if &filetype ==# 'vim'
let comment_string = '"'
elseif &filetype ==# 'cpp'
let comment_string = '\/\/'
endif
let line = getline('.')
if line =~ '^' . comment_string
"Comment.
" How could I do the equivalent of "shift-I to go to the beginning of the
" line, then enter comment_string"?
else
"Uncomment. This is flawed too. Maybe I should just go to the beginning of
"the line and delete a number of characters over?
execute 's/^' . comment_string . '//'
endif
endfunction
无论该线是否被注释,我得到的取消注释的一件事是
Pattern not found: ^"
(我在我的vimrc文件上测试过。)
建议赞赏 - 我觉得这不应该太复杂。
答案 0 :(得分:2)
您可以在函数声明之后使用range
选项,它允许您使用包含范围的开头和结尾的两个变量a:firstline
和a:lastline
。
在execute
指令内部将它们添加到替换命令之前,仅在该范围内执行它。在删除对变量应用escape()
以避免正斜杠碰撞时:
function! ToggleComment() range
let comment_string = ''
if &filetype ==# 'vim'
let comment_string = '"'
elseif &filetype ==# 'cpp'
let comment_string = '//'
endif
let line = getline('.')
if line =~ '^' . comment_string
execute a:firstline . "," . a:lastline . 's/^' . escape(comment_string, '/') . '//'
else
execute a:firstline . "," . a:lastline . 's/^/\=printf( "%s", comment_string )/'
endif
endfunction
UPDATE :要在第一个非空白字符之前添加和删除注释,必须在行开头的零宽度断言后添加可选空格。这是改变的部分。请注意我如何将\s*
添加到比较中,如果它在该行中存在评论并在替换的替换部分中添加\1
或submatch(1)
:
if line =~? '^\s*' . comment_string
execute a:firstline . "," . a:lastline . 's/^\(\s*\)' . escape(comment_string, '/') . '/\1/'
else
execute a:firstline . "," . a:lastline . 's/^\(\s*\)/\=submatch(1) . printf( "%s", comment_string )/'
endif
答案 1 :(得分:0)
这可能会失败,因为您的:s
命令找不到注释字符串。您应该在e
命令中使用:s
标志(另请参阅:h s_flags
)。
此外,我认为你想在行开头和注释字符串之间添加可变数量的空格,例如像if line =~ '^\s*'.comment
这样的东西,所以它正确地抓住了:
#This is a comment
#This is a comment
等等,你会明白的。