是否有可能在操作符暂挂映射中确定运动是线性的,块方向的还是法线方向的?



当使用omaponoremap声明映射时,我希望能够处理运动将是块方向,直线方向或标准方向的情况。

例如,让我们考虑下面的代码块:
abcd
efgh
ijkl
mnop

光标在字母f上。假设我定义了一个从K:normal! vjl的操作符映射(到字母k)。

onoremap K :normal! vjl<cr>

有趣的是,当我运行dvK, dK, d^VK时,我分别得到

abcd   abcd   abcd
el     el     eh
mnop   mnop   il
              mnop

但是当我运行dVK时它不会工作,我得到与dvK完全相同的结果。

我试图使用visualmode()(映射定义为@=visualmode()<cr>jl<cr>,但这不起作用。当您在操作符挂起模式下使用v, V或CTRL-V时,此函数的返回值似乎不会立即受到影响。

有人知道吗?
谢谢你

要达到您想要的效果,您可以简单地定义

onoremap K :<c-u>normal! jl<cr>

注意这个由前命令形成的动作,总是按字符顺序(参见:h movement

)

然后你可以自由地使用dv,或dV,或d^V来强制运动为另一种类型,并得到你想要的。

我已经写了一些关于操作符挂起映射的答案。在其中的1中,我勾勒了一个函数的轮廓,该函数应该根据文档处理各种情况(字符,行,块明智的选择):

 g@{motion}     Call the function set by the 'operatorfunc' option.
        The '[ mark is positioned at the start of the text
        moved over by {motion}, the '] mark on the last
        character of the text.
        The function is called with one String argument:
            "line"  {motion} was |linewise|
            "char"  {motion} was |characterwise|
            "block" {motion} was |blockwise-visual|
        Although "block" would rarely appear, since it can
        only result from Visual mode where "g@" is not useful.
        {not available when compiled without the |+eval|
        feature}

下面是一个使用<F4>计算空格数的例子:>

nmap <silent> <F4> :set opfunc=CountSpaces<CR>g@
vmap <silent> <F4> :<C-U>call CountSpaces(visualmode(), 1)<CR>
function! CountSpaces(type, ...)
  let sel_save = &selection
  let &selection = "inclusive"
  let reg_save = @@
  if a:0  " Invoked from Visual mode, use '< and '> marks.
    silent exe "normal! `<" . a:type . "`>y"
  elseif a:type == 'line'
    silent exe "normal! '[V']y"
  elseif a:type == 'block'
    silent exe "normal! `[<C-V>`]y"
  else
    silent exe "normal! `[v`]y"
  endif
  echomsg strlen(substitute(@@, '[^ ]', '', 'g'))
  let &selection = sel_save
  let @@ = reg_save
endfunction

1 vim从vmap内部调用函数

最新更新