0

我目前正在为 Vim 编写一个插件,我希望它在执行后恢复默认寄存器。但是,有问题的函数是通过<C-r>=Myfunction()<CR>构造调用的,这意味着我需要在函数返回后恢复它。我试过这样做:

inoremap <silent> <Space> <C-r>=Myfunction()<CR>
function! Myfunction()
    let oldreg      = getreg('"')
    let oldregtype  = getregtype('"')
    let restore     = "\<ESC>:call setreg('\"','".oldreg."','".oldregtype."')\<CR>a"

    let @" = "whatever"

    return "\<ESC>yya ".restore
endfunction

可以看到,"寄存器受返回字符串影响,所以不能直接调用setreg。显然这个函数并没有真正做任何事情,但我使用的实际函数很长。另外,如果该字符串有点难以阅读,我深表歉意,但我不确定是否有任何其他方法可以完成此操作。总而言之,当寄存器包含一个单词时,该函数似乎可以工作,但每当寄存器中有换行符时,该函数就会失败。(具体错误E115: Missing quote与 oldreg 参数有关。)我试图通过首先对 oldreg 进行脱壳来解决这个问题;但是,这会导致错误E121: Undefined Variable,其中未定义的变量是我的寄存器中的内容。关于这里可能出了什么问题的任何想法?

编辑:我找到了解决方案。它很毛茸茸,但到目前为止效果很好。以下是如何将解决方案应用于我的示例代码,以防万一它对那里的任何人有所帮助。

inoremap <silent> <Space> <C-r>=Myfunction()<CR>
function! Myfunction()
    let oldreg      = substitute(escape(getreg('"'), '\\'), '\n', '\\n', 'g')
    let oldregtype  = getregtype('"')
    let restore     = "\<ESC>:call setreg('\"',\"".oldreg."\",'".oldregtype."')\<CR>a"

    let @" = "whatever"

    return "\<ESC>yya ".restore
endfunction
4

2 回答 2

0

在返回函数后,不要进入正常模式,我认为你应该进入它。这样就可以 setreg()正常调用了。例如:

function! Myfunction()
    let oldreg      = getreg('"')
    let oldregtype  = getregtype('"')

    let @" = "whatever"

    normal! yya 

    setreg('"', oldreg, oldregtype)
endfunction
于 2017-03-06T23:14:58.100 回答
0

这是一种继续的方法:Vim:如何在不覆盖寄存器的情况下粘贴

从那时起,我们就获得了天赋setreg(),而且我还开发了一个更通用的解决方案,简化了最有用的东西的恢复 ( lh#on#exit())。

在所有情况下,解决方案都是 return @=FunctionToExecute(),并且恢复将发生在该函数中。

但正如其他人所说,您可能需要更明确地了解您的需求,因为可能存在更具体的解决方案来解决这些问题。例如,您可以简单地使用 不修改所有寄存器的函数,而不是用yy或 with拉动。对于换行,有,但这会破坏重做和其他事情。:yankgetline()setline()

于 2017-03-06T23:22:55.507 回答