Vim内联重映射以检查第一个字符

时间:2012-08-08 16:00:54

标签: vim if-statement inline remap

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

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

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

我原来是这样的:

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

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

3 个答案:

答案 0 :(得分:4)

vim有许多评论插件:

我强烈建议您在决定推出自己的插件之前先看一下这些插件。它会为你节省很多精力。

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

如果你已经开始创建自己的映射,我建议你创建一个函数来完成所有的努力,并通过:call进行映射调用。如果您认为可以使用不需要函数的简单逻辑,那么您可以使用表达式映射(请参阅:h map-<expr>)。您可能希望组织成一个插件,因为它可能很大。如果是这种情况,请查看:h write-plugin以表达您的感受 以适当的方式编写插件。

切换注释的简单表达式映射示例:

nnoremap <expr> <leader>c getline(".") =~ '\m^\s*\/\/' ? '^"_2x' : 'I//<esc>`['

答案 1 :(得分:3)

我完全同意@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一样,从长远来看,您可能会发现其他插件更灵活。

答案 2 :(得分: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