How to clear vim registers effectively?

VimVim Registers

Vim Problem Overview


Registers in vim are a great feature to store text snippets and even to run commands on the text stored within them. However, I'm a tidy person and tend to clean things up when I'm done.

I know that if I wanted to clear register a, I can use qaq.

I can also execute the following command:

:let @a = ''

However, these solutions seem like a mere workaround to the problem. When I execute :registers, the list still displays register a (with an empty value), while registers that have otherwise never been used are not displayed.

Is there a way to clear a register with the side-effect of removing the register from this list?

And if so, is there also a way to clear all registers at once, i.e., to reset that list of registers?

Vim Solutions


Solution 1 - Vim

Since that venerable answer on the mailing list, linked by @romainl, we have setreg('a', []) that clears the register.

Thus, the code could become:

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

Solution 2 - Vim

AFAIK you can't use built-in commands/functions to make registers disappear from the list. That seems to be doable only by removing them from your ~/.viminfo which sounds a bit extreme.

this thread on the vim mailing list has a command that clears every register but it doesn't remove them from :reg:

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

--- EDIT ---

The command above is no longer needed but here is a breakdown for the curious:

" 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

Solution 3 - Vim

Put this in your .vimrc:

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

and clear every register with :WipeReg

If you would like that to happen every time you start Vim also add:

autocmd VimEnter * WipeReg

Solution 4 - Vim

Remove .viminfo file or delete the register line in the .viminfo file.

You can get the details from 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

Solution 5 - Vim

Another option is to never load any registers. As others have said, registers are loaded from .viminfo. The -i flag is used to specify what viminfo file to use. If you specify NONE, no viminfo, and therefore no registers will be loaded.

vim -i NONE

Solution 6 - Vim

It is possible to set a value for each used register, similar to romainl's approach:

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

This avoids including additional register on the output of :registers

Solution 7 - Vim

For the sake of completeness, I'll note that while setting a register to contain an empty string doesn't remove the register from the output of the :registers command, Vim does not save registers which have been cleared in this way to the .viminfo file.

Therefore, one other quick-and-dirty alternative for removing specific registers from the list is to clear them using either of the commands you suggest, and then restart Vim.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRobin KloseView Question on Stackoverflow
Solution 1 - VimLuc HermitteView Answer on Stackoverflow
Solution 2 - VimromainlView Answer on Stackoverflow
Solution 3 - VimlaktakView Answer on Stackoverflow
Solution 4 - VimMarsloView Answer on Stackoverflow
Solution 5 - VimDJMcMayhemView Answer on Stackoverflow
Solution 6 - VimmMontuView Answer on Stackoverflow
Solution 7 - VimRichView Answer on Stackoverflow