【问题标题】:Restoring a register after a <C-r> function call在 <C-r> 函数调用后恢复寄存器
【发布时间】:2017-07-26 21:09:57
【问题描述】:

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

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。显然这个函数并没有真正做任何事情,但我使用的实际函数很长。另外,如果该字符串有点难以阅读,我深表歉意,但我不确定是否有其他方法可以完成此操作。总而言之,当寄存器包含一个单词时,该函数似乎可以工作,但每当寄存器中有换行符时,该函数就会失败。 (关于 oldreg 参数的具体错误是 E115: Missing quote。)我试图通过首先对 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

【问题讨论】:

  • 目前,您的示例对我来说没有多大意义,因为我看不出是什么阻碍了您在函数末尾直接调用setreg。是什么阻碍了这一点?为什么在调用函数后需要将其重置?如果函数只返回一个字符串?您需要在其他地方使用"@ 吗?仅当您需要在通话中的 MyFunction 结束和 &lt;CR&gt; 之间使用它时,这才有意义,无论如何都不会发生。抱歉,我的评论没有回答问题,我只是想了解您的目标,因为似乎还有其他方法可以做到这一点。 :)
  • @sidyll vim 中没有名为@ 的寄存器。
  • 所以最好将问题 [on-hold] 待进一步澄清。
  • @sidyll @ 寄存器是未命名寄存器的别名。我忘了" 通常是寄存器的更传统的符号。我已经编辑了函数以显示在返回字符串中使用了寄存器,所以很遗憾,我不能简单地正常调用 setreg。

标签: vim restore vim-registers


【解决方案1】:

这里有一个方法:Vim: how to paste over without overwriting register

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

在所有情况下,解决方案都是返回@=FunctionToExecute(),然后在该函数中进行恢复。

但正如其他人所说,您可能需要更明确地说明您的需求,因为可能存在更具体的解决方案来解决这些问题。例如,不用yy:yank 拉取,您可以简单地使用getline() 函数,让所有寄存器都保持不变。对于换行,有setline(),但这会破坏重做和其他事情。

【讨论】:

  • 您的建议有效,因此我将其标记为正确。但是,我发现一个稍微不同的解决方案更适合我的程序结构。
【解决方案2】:

我认为在返回函数后不要进入正常模式 你应该进去。这样就可以正常拨打setreg() 在里面。例如:

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

    let @" = "whatever"

    normal! yya 

    setreg('"', oldreg, oldregtype)
endfunction

【讨论】:

    猜你喜欢
    • 2011-10-15
    • 1970-01-01
    • 2021-02-15
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    相关资源
    最近更新 更多