2

我正在尝试使用内联在 Vim 中进行评论重新映射,if以检查它是否已被评论。这是我已经拥有的,当然它不起作用哈哈:

imap <c-c> <Esc>^:if getline(".")[col(".")-1] == '/' i<Delete><Delete> else i// endif

我想要做的是检查第一个字符是否为 a /。如果是 a/则删除该行的前两个字符,如果不是 a则在该行前面/添加两个字符。//

我原来是这样的:

imap <c-c> <Esc>^i//

这很有效,但我想要的是能够随心所欲地评论/取消评论。

4

3 回答 3

4

我完全同意@Peter Rincker 的回答警告不要在插入模式下执行此操作,并为您指出功能齐全的插件。

然而,我忍不住写了这个函数来精确地做你要求的事情。我发现用函数处理这种映射更容易。作为一个额外的好处,它可以让您在开始时所在行的同一位置返回插入模式(已通过插入或删除字符进行了移动)。

function! ToggleComment()
    let pos=getpos(".")
    let win=winsaveview()
    if getline(".") =~ '\s*\/\/'
        normal! ^2x
        let pos[2]-=1
    else 
        normal! ^i//
        let pos[2]+=3
    endif
    call winrestview(win)
    call setpos(".",pos)
    startinsert
endfunction   

inoremap <c-c> <Esc>:call ToggleComment()<CR>

请注意pos确保光标返回到正确列的修改。该命令startinsert在此类函数中很有用,可返回插入模式。使用映射总是更安全noremap,除非有充分的理由不这样做。

这似乎工作得很好,但它不是很像 Vim,从长远来看,您可能会发现其他插件更灵活。

于 2012-08-08T16:36:10.910 回答
4

vim 有很多评论插件:

我强烈建议您在决定推出自己的插件之前先看看这些插件。它将为您节省大量精力。

作为旁注,您通常希望在正常模式而不是插入模式下评论/取消评论。这不仅是 vim 的方式,而且还会提供更好的撤消历史记录。

如果您对创建自己的映射一无所知,我建议您创建一个函数来完成所有艰苦的工作,并让您的映射通过:call. 如果您认为可以使用不需要函数的简单逻辑,那么您可以使用表达式映射(请参阅 参考资料:h map-<expr>)。您可能希望组织成一个插件,因为它可能很大。如果是这种情况,请查看以:h write-plugin正确的方式编写插件的感觉。

用于切换评论的简单表达式映射示例:

nnoremap <expr> <leader>c getline(".") =~ '\m^\s*\/\/' ? '^"_2x' : 'I//<esc>`['
于 2012-08-08T16:28:26.677 回答
1

还有这个vimtip! http://vim.wikia.com/wiki/Comment/UnComment_visually_selected_text

我用底部的

...
noremap <silent> ,c :<C-B>sil <C-E>s/^/<C-R>=escape(b:comment_leader,'\/')<CR>/<CR>:noh<CR>
noremap <silent> ,u :<C-B>sil <C-E>s/^\V<C-R>=escape(b:comment_leader,'\/')<CR>//e<CR>:noh<CR>

,c comments out a region
,u uncomments a region
于 2012-08-08T18:16:07.573 回答