neo如何在Vim中获得当前命令寄存器值/名称?



目前我有这个映射:

nmap <silent> x :set opfunc=SpecialChange<CR>g@
function! SpecialChange(type)
silent exec 'normal! `[v`]"_dP'
endfunction

它帮我替换一些默认值寄存器值。

然而,我希望能够用一些特定的寄存器替换该值,为此,我需要知道当前命令寄存器的值或名称(或更好的两者)。例如,当我按下"axiw"时,我想用a寄存器替换单词,但我需要了解a寄存器被按下而不是bc或其他东西。有办法做到这一点吗?

: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,charblock,因此我们跳过条件并直接进入函数的核心,在那里我们可以使用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