2013-07-18 106 views
0

我想写一个插件,涉及向上或向下移动可变数量的行。我想创建一些可以用作自定义运动的东西,以用于常规,可视化和运营商待定模式。在视觉模式中造成这种奇怪的运动行为是什么?

这里的想法的一个小片段:(“3”以下是该示例的目标是将可变数量的线,但是这是不相关的我的问题是什么。)

function! MoveDownThreeLines(mode) 
    if a:mode == 'v' 
     normal! gv 
    endif 

    if a:mode == 'o' 
     normal! V3j 
    else 
     normal! 3j 
    endif 
endfunction 

nnoremap w :call MoveDownThreeLines('n')<CR> 
vnoremap w :call MoveDownThreeLines('v')<CR> 
onoremap w :call MoveDownThreeLines('o')<CR> 

这个片段的目标是创建一个向下移动三行的自定义动作。然后,我想要w的行为与3j的行为相同。在正常模式下,它像预期的那样向下移动三条线,并且在操作员待定模式中,操作员按预期行动四条线(当前和下面三条线)。 (虽然我不得不使用V来强制运动,这很奇怪,因为j已经是一个线性运动了。有没有人知道这是为什么?)

问题出在视觉模式。如果我进入可视模式,请按w,光标向下移动三行,如预期。但是,如果我再次按w,它只能向下移动两行。

同样,如果我进入视觉模式并以某种其他方式向下延伸选择,则按w只能向下移动两行。另一个奇怪的问题是,如果我进入可视模式并向上扩展选择,w将我的选择从旧选择的底部改变为两行。 (目标是w将选区的顶部向下移动三行,就像我使用3j一样。)

如何在所有情况下使w向下移动三行?

PS:Ingo Karkat,如果你碰巧读到这个,感谢你的评论颇高的camelcasemotion脚本 - 这需要一些想法。

+2

这是一个好的做法,加上''来清除视觉范围'<,'>'的一部分。 'vnoremap w: call MoveDownThreeLines('v')' –

+0

'gv'在每次执行时将光标向上移动,除了第一次执行。 – FDinoff

+0

@PeterRincker对,我忘记了!对于稍后阅读这些内容的人来说,这不仅仅是良好的做法,它还会在执行方面产生影响。这就是这里的错误。感谢您指出了这一点!如果你想发布这个答案,我会去接受它。 – pandubear

回答

3

您应该预先所有(不只是视觉的方式之一,彼得Rincker评论)映射与<C-u>,因为你可能要提供与您的映射一个[count](而不是硬编码3)。

在正常模式下,当按下:时,计数(例如3)被翻译成:.,+2。同样,视觉模式:预先:'<,'>:call命令为每行执行一次函数,这通常不是您想要的。 (您可以通过附加range关键字到:function定义,但避免计数被转换成一个范围,您可以使用它更加灵活地改变,你可以用v:count使用它自己的函数中。)

+0

对,谢谢。这就说得通了。但是,为什么你应该用''作为前缀映射操作符呢? – pandubear

+0

您不需要,因为即时计数没有正常模式的行为,但我不知道这是错误还是意图。最好保持一致,因为它肯定不会受到伤害。 –

+0

+1关于'' –

相关问题