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,如果你碰巧读到了这篇文章,谢谢你对骆驼案情脚本的好评——这需要一些想法。

4

1 回答 1

3

您应该在所有(不仅仅是视觉模式之一,正如 Peter Rincker 评论的那样)映射前加上<C-u>,因为您可能希望为[count]您的映射提供 a (而不是硬编码的 3)。

在正常模式下,按下:.,+2时会转换为计数(例如 3) 。:同样,视觉模式:前置:'<,'>. 该命令对每一行:call执行一次函数,这通常不是您想要的。(您可以通过将关键字附加到定义来更改它,但避免将计数转换为范围可以让您更灵活地使用它;您可以在函数中使用它。)range:functionv:count

于 2013-07-19T06:36:28.053 回答