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

Vim内联重新映射以检查第一个字符,vim,if-statement,inline,remap,Vim,If Statement,Inline,Remap,我试图在Vim中使用内联if进行注释重新映射,以检查它是否已经被注释。这是我已经做过的,当然不起作用了哈哈: imap <c-c> <Esc>^:if getline(".")[col(".")-1] == '/' i<Delete><Delete> else i// endif 这非常有效,但我希望能够随心所欲地评论/取消评论。vim有许多评论插件: 还有更多 我强烈建议您在决定推出自己的插件之前,先看看这些插件。这将为你节省大量的

我试图在Vim中使用内联
if
进行注释重新映射,以检查它是否已经被注释。这是我已经做过的,当然不起作用了哈哈:

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

这非常有效,但我希望能够随心所欲地评论/取消评论。

vim有许多评论插件:

  • 还有更多
我强烈建议您在决定推出自己的插件之前,先看看这些插件。这将为你节省大量的精力

作为旁注,您通常希望在正常模式而不是插入模式下进行注释/取消注释。这不仅是vim方式,而且还将提供更好的撤销历史

如果您一心想创建自己的映射,我建议您创建一个函数来完成所有的艰苦工作,并让您的映射通过
:call
调用该函数。如果您认为可以使用不需要函数的简单逻辑,那么可以使用表达式映射(请参见
:hmap-
)。你可能想要组织成一个插件,因为它可能很大。如果是这样的话,请查看
:h编写插件
,给您一种感觉
以正确的方式编写插件

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

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

我完全同意@Peter Rincker的回答,他警告不要在插入模式下这样做,并建议您使用功能齐全的插件

但是,我忍不住编写了这个函数,以完全满足您的要求。我发现用函数处理这种映射更容易。作为一个额外的好处,它会使您返回到开始时所在行的相同位置的插入模式(通过插入或删除字符进行了转换)

function!ToggleComment()
设pos=getpos(“.”)
let win=winsaveview()
如果getline(“.”=~'\s*\/\/'
正常!^2x
设pos[2]=1
其他的
正常!^i//
设pos[2]+=3
恩迪夫
调用winrestview(win)
呼叫设置位置(“.”,位置)
startinsert
端功能
inoremap:calltogglecomment()
请注意对
pos
的修改,以确保光标返回到正确的列。在这种类型的函数中,命令
startinsert
可用于返回插入模式。除非有很好的理由,否则使用
noremap
进行映射总是比较安全的


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

还有这个vimtip

我用最下面的那个和

...
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
。。。
noremap,c:sil s/^/=escape(b:comment\u leader,\/')/:noh
noremap,u:sil s/^\V=escape(b:comment\u leader,\/')//e:noh
,c注释出一个区域
,u取消区域注释

我并不想粗鲁,但为什么要重新发明轮子呢?我会选择小而强大的插件我尝试了很多插件,但都没有成功:(谢谢,我尝试了这些插件,但没有成功:(因此,因为这是一个只对PHP使用//的简单注释,所以我想:)您可能希望通过
:version
验证您是否拥有正常或大型版本的vim。也请严格遵循插件说明。如果您确实想要使用插件,我建议您使用病原体:或Vundle:哇!非常感谢!当我尝试创建任何函数时,我无法让函数为我工作,因此我不再尝试:(但那太棒了!在这里你需要小心。如果你在一行的开头或结尾切换注释,它将无法正确恢复位置。你可能还需要提到使用
u
将更改分解为两个单独的撤消块。它实际上不需要恢复位置,至少对我来说不需要,我不明白为什么我需要小心。)。它正是我所需要的,注释和取消注释,简单而有效。如果是这样的话,那么这应该是理想的:
nnoremap c getline(“.”=~'^\s*\/\/\/'?“^”\u 2x':'I/`['
。这将创建到
c
的正常模式映射,通常转换为
\c
(请参见
:h mapleader
)。它不会屏蔽有用的插入模式映射(请参见
:hi_ctrl-c
)。它与撤消历史很好地配合。它更简单、更短。注意:这使用表达式映射(请参见
:h map-
),因此您必须拥有Vim 7+。
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>
...
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