当使用omap
或onoremap
声明映射时,我希望能够处理运动将是块方向,直线方向或标准方向的情况。
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内部调用函数