目前我有这个映射:
nmap <silent> x :set opfunc=SpecialChange<CR>g@
function! SpecialChange(type)
silent exec 'normal! `[v`]"_dP'
endfunction
它帮我替换一些默认值寄存器值。
然而,我希望能够用一些特定的寄存器替换该值,为此,我需要知道当前命令寄存器的值或名称(或更好的两者)。例如,当我按下"axiw"
时,我想用a
寄存器替换单词,但我需要了解a
寄存器被按下而不是b
或c
或其他东西。有办法做到这一点吗?
从:help :map-operator
提供的示例中获得灵感,您的函数应该是这样的:
nnoremap <expr> <key> SpecialChange()
function! SpecialChange(type = '')
if a:type == ''
set opfunc=SpecialChange
return 'g@'
endif
execute 'normal! `[v`]"_d"' .. v:register .. 'P'
endfunction
解释:
我们使用
<expr>
映射,因为这个引号:使用
<expr>
映射来获取任何前缀计数和寄存器。SpecialChange()
接受单个type
参数,默认值为空字符串。当不带参数调用时,该函数将
opfunc
设置为自身并最终返回g@
。这是另一种方法::set opfunc=SpecialChange<CR>g@
当作为
operatorfunc
调用时,SpecialChange()
获得type
参数,其值为line
,char
或block
,因此我们跳过条件并直接进入函数的核心,在那里我们可以使用v:register
,因为我们处于<expr>
映射中:execute 'normal! `[v`]"_d"' .. v:register .. 'P'
这都是人为的,但这是我们必须处理的。
我想我丢失了当前的寄存器名称。以下是对我有效的解决方案:
nmap x :call SetActiveRegister()<CR>:set opfunc=SpecialChange<CR>g@
let g:activeRegisterName = ''
function! SpecialChange(type)
silent exec 'normal! `[v`]"_di' .. getreg(g:activeRegisterName)
endfunction
function! SetActiveRegister()
let g:activeRegisterName = v:register
endfunction