从视觉模式到切换评论的简单vim功能(学习练习)

时间:2013-09-27 20:57:59

标签: vim

部分用于练习,部分用于个人用途,我希望能够进入视觉模式,选择一些线条,然后点击“,”然后切换评论。 (我知道NerdCommenter存在,但我想要一些简单而没有任何想象力的东西 - 而且,这也是实践。)

我了解到你可以通过'& filetype'来访问文件类型,并且'''。连接字符串,==#是区分大小写的字符串比较,=〜是正则表达式匹配。我还了解到getline('。')获取了视觉模式突出显示的行(如果突出显示多行,则为每行)。

这是我的(有缺陷的)

的.vimrc

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文件上测试过。)

建议赞赏 - 我觉得这不应该太复杂。

2 个答案:

答案 0 :(得分:2)

您可以在函数声明之后使用range选项,它允许您使用包含范围的开头和结尾的两个变量a:firstlinea: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*添加到比较中,如果它在该行中存在评论并在替换的替换部分中添加\1submatch(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
等等,你会明白的。