是否有可能在运算符挂起的映射中确定运动是线性,块状还是正常?

时间:2011-12-19 16:20:13

标签: vim

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

例如,让我们考虑以下块:

abcd
efgh
ijkl
mnop

光标位于字母f上。假设我定义了从K:normal! vjl的运算符映射(转到字母k)。

onoremap K :normal! vjl<cr>

有趣的是,当我运行dvKdKd^VK时,我分别得到了

abcd   abcd   abcd
el     el     eh
mnop   mnop   il
              mnop

但是,当我运行dVK时,它将无效,我与dvK完全相同。

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

有人有线索吗?
谢谢

2 个答案:

答案 0 :(得分:0)

我已经在操作员挂起的映射上写了一些答案。在one of them 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>计算空格数的示例:&gt;

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 call a function from inside a vmap

答案 1 :(得分:0)

要实现您的目标,您只需定义

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

请注意,由ex命令形成的此动作始终是字符(请参阅:h movement

然后,您可以自由使用dvdVd^V来强制将动作变为另一种类型,并获得您想要的效果。