如何有效地清除 vim 寄存器?

Posted

技术标签:

【中文标题】如何有效地清除 vim 寄存器?【英文标题】:How to clear vim registers effectively? 【发布时间】:2013-10-26 03:33:48 【问题描述】:

vim 中的寄存器是一个很棒的功能,可以存储文本 sn-ps,甚至可以对存储在其中的文本运行命令。不过,我是个爱整洁的人,收拾完东西后会收拾干净。

我知道如果我想清除寄存器a,我可以使用qaq

我也可以执行以下命令:

:let @a = ''

但是,这些解决方案似乎只是解决问题的一种方法。当我执行:registers 时,列表仍然显示寄存器a(具有空值),而不会显示从未使用过的寄存器。

有没有办法清除一个带有从该列表中删除该寄存器的副作用的寄存器?

如果是这样,是否还有一种方法可以一次清除所有寄存器,即重置该寄存器列表?

【问题讨论】:

我想我是一个整洁的人---我从不看:reg 【参考方案1】:

AFAIK 您不能使用内置命令/函数使寄存器从列表中消失。这似乎只能通过从您的 ~/.viminfo 中删除它们来实现,这听起来有点极端。

this thread on the vim mailing list 有一个命令可以清除所有寄存器,但不会从:reg 中删除它们:

let regs='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/-"' | let i=0 | while (i<strlen(regs)) | exec 'let @'.regs[i].'=""' | let i=i+1 | endwhile | unlet regs

--- 编辑 ---

上面的命令不再需要,但这里是好奇的细分:

" The value of variable regs is a string made up of all named
" and numbered registers, plus the search, small delete, and
" unnamed registers. A string can be used as a list for our
" use case so we use the most concise method. We could have
" done let regs = ['a', 'b', 'c', etc. instead.
let regs = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/-"'

" We are going to iterate through the string so we initialize
" a loop counter with value 0.
let i = 0

" Here is our loop where we check at each iteration if the loop
" counter is smaller than the length of regs.
while (i < strlen(regs))

    " If it is, we programmatically assign an empty string
    " to each corresponding register
    exec 'let @' . regs[i] . ' = ""'

    " and we add 1 to the loop counter.
    let i = i + 1
endwhile

" Once we are done, we get rid of the variable we created above
" which is now unnecessary.
unlet regs

【讨论】:

嗯。同样的策略确实可以清除搜索寄存器。 :map &lt;silent&gt; &lt;F2&gt; :let @/ = "" 可惜它不符合 OP 的要求。 您好 romainl 和 jpaugh,在您的两个 cmets 中,您指示使用未命名寄存器“”中的内容覆盖每个寄存器的内容。但是让我困惑的是为什么当前的未命名寄存器应该是空的?我们至少应该先清除未命名的寄存器,然后将“空白”分配给每个寄存器,不是吗?但可悲的是,不知何故,你的指示工作正常。我对 VimL 一无所知。 @leoleohu,没有。该命令为每个寄存器分配一个空字符串,而不是未命名寄存器的内容。我可以看到混淆可能来自哪里,所以我会在我的答案中添加一些解释。请注意,Luc Hermitte 的答案现在是正确的,因此您可能不应该过多关注这个。 @romainl,你的更新解释了。我现在明白 "" 代表一个空字符串,而不是未命名的寄存器。这种误解来自于我在 VimL 中缺少的知识。非常感谢。【参考方案2】:

删除.viminfo文件或删除.viminfo文件中的寄存器行。

您可以从Here获取详细信息:

The viminfo file is used to store:
- The command line history.
- The search string history.
- The input-line history.
- Contents of non-empty registers.
- Marks for several files.
- File marks, pointing to locations in files.
- Last search/substitute pattern (for 'n' and '&').
- The buffer list.
- Global variables

【讨论】:

【参考方案3】:

可以为每个使用的寄存器设置一个值,类似于 romainl 的方法:

function! ClearRegisters()
   redir => l:register_out
   silent register
   redir end
   let l:register_list = split(l:register_out, '\n')
   call remove(l:register_list, 0) " remove header (-- Registers --)
   call map(l:register_list, "substitute(v:val, '^.\\(.\\).*', '\\1', '')")
   call filter(l:register_list, 'v:val !~ "[%#=.:]"') " skip readonly registers
   for elem in l:register_list
      execute 'let @'.elem.'= ""'
   endfor
endfunction

这避免了在:registers 的输出中包含额外的寄存器

【讨论】:

【参考方案4】:

另一个选择是从不加载任何寄存器。正如其他人所说,寄存器是从.viminfo 加载的。 -i 标志用于指定要使用的 viminfo 文件。如果指定NONE,则没有viminfo,因此不会加载任何寄存器。

vim -i NONE

【讨论】:

这很好,但是你当然失去了 .viminfo 文件的好处。那真不幸。仍然是一种有效的方法。【参考方案5】:

由于邮件列表上的可靠答案通过@romainl 链接,我们有setreg('a', []) 清除了注册。

因此,代码可能变成:

let regs=split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/-"', '\zs')
for r in regs
  call setreg(r, [])
endfor

【讨论】:

哇——这实际上将它从:registers 列表中删除了!谢谢!! ^u^ 不适合我; :exec setreg('a', []) 给了我E730: using List as a String 并且不删除也不清空寄存器。 在某个时间点,vim 已经开始拒绝:let a =1 + :let a = 。在去年,这被恢复了。我怀疑你在这两个补丁之间的某个时间点编译了一个 vim 版本。 @dgmstuart,你的理解是正确的。因此,似乎将一个空列表附加到一个寄存器不会对其进行修改。 @Atralb 注意:不是:execute,而是:call。使用exe,你尝试执行setreg()的结果应该是0(一个没有返回值的函数将在vim脚本中返回0),这意味着这将执行:0,IOW,它会移动光标到第一行。关于nvim,我不知道。尝试查看 :h setreg() 返回的内容,以防 nvim 有一些特定的参数组合。也许你应该尝试在 nvim 邮件列表上询问——我想有一个。【参考方案6】:

把这个放在你的.vimrc:

command! WipeReg for i in range(34,122) | silent! call setreg(nr2char(i), []) | endfor

并使用:WipeReg清除所有寄存器

如果您希望每次启动 Vim 时都发生这种情况,请添加:

autocmd VimEnter * WipeReg

【讨论】:

【参考方案7】:

为了完整起见,我会注意,虽然设置寄存器包含空字符串并不会从:registers 命令的输出中删除该寄存器,但 Vim 不会保存已在此命令中清除的寄存器.viminfo 文件的路径。

因此,从列表中删除特定寄存器的另一种快速而简单的方法是使用您建议的任一命令清除它们,然后重新启动 Vim。

【讨论】:

以上是关于如何有效地清除 vim 寄存器?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地将 zmm 寄存器的低 64 位保存到内存中?

测试 256 位 YMM AVX 寄存器为零的最有效/惯用方法

vim 下粘贴复制,如何做到最快

有效地将 YMM 寄存器的低 64 位设置为常数

在单臂霓虹灯寄存器中有效地将 8 位数字扩展到 12 位

单片机编程中 如何清除串口接收寄存器中的值,即清除SBUF中的值