0

Is there a nondestructive way to search a pattern in all registers, like redirecting :reg to some register and then paste it to a new buffer and perform the search there?

3

You can have the list of registers that match a pattern with:

:let regs=split('abcdefghijklmnopqrstuvwxyz0123456789/-".', '\zs')

:echo filter(regs, 'getreg(v:val) =~ "the_pattern"')

Or if you really prefer to paste all registers into a buffer in order to search interactively (and not programmatically) -- I leave the creation of scratch buffer out

:let regs=split('abcdefghijklmnopqrstuvwxyz0123456789/-".', '\zs')
:call map(regs, '"\"".v:val. "  ".getreg(v:val)')
:put=regs

" or, if neither the noise nor the joined lines bother you
put=execute('registers')
  • :echo filter(regs, 'getreg(v:val) =~ "the_pattern"') desn't work (gives []) – user10982983 Apr 10 at 11:43
  • @user10982983 What is you pattern? Have you seen there are two strings embedded? Also, this is a program oriented solution, from this you have a list and can do whatever you wish with it. To display it, join(thelist, "\n") is often required for instance. – Luc Hermitte Apr 10 at 12:29
  • Now it is ok, the problem was that filter destroys the regs variable and therefore the list with the register names must be generated every time before calling the filter. Thanks! – user10982983 Apr 10 at 13:15
  • Oh. Yes indeed. The other possibility in those cases is to copy(res) in filter() call. – Luc Hermitte Apr 10 at 13:44
2

Just create a new unnamed buffer and then put the output of :reg into it with

:enew
:put =execute('reg')

Note that the output of :reg is truncated to terminal width.

Where = is the "expression register" and execute('reg') is the expression. See :help @=.

The function execute() executes a command and returns the output as string. See :help execute().


Or, to show the power of Vim:

command -nargs=1 RegSearch echo join(filter(split(execute('reg'), "\n"), {i, v -> v =~ <q-args>}), "\n")

Inner-to-outer:

  • execute('reg') is already known
  • split(..., "\n") split into a list of lines
  • filter(..., {i, v -> v =~ <q-args>}) only keep those line that match the commands argument (see :help <q-args> and :help lambda)
  • join(..., "\n") join the kept list elements into a string separated by newlines.

Then use it like this:

:RegSearch <searchterm>

Searchterm is a regular expression. If it contains whitespaces, they have to be escaped with a backslash.

I love it when it is doable on one line :-). And then Christian writes a comment ... :-/ He is right.

  • 1
    Note, that :reg truncates the register content. So it might not match. In theory, one should be able to do something like this as well: :filter /patter/ :reg, however, the :reg command is not supported by the :filter command. Sounds like a plausible whishlist bug to me – Christian Brabandt Apr 9 at 17:26
1

Here is a gist from romainl

Here is my tweaked version of the gist.

" Redirect the output of a Vim or external command into a scratch buffer
command! -nargs=1 Redir
            \ tabnew |
            \ setlocal nobuflisted buftype=nofile bufhidden=wipe noswapfile |
            \ call setline(1, split(execute(<q-args>), "\n"))

Now, you can do :Redir reg to open a new tabpage with output of :reg. Then do what you gotta do.

  • 1
    Now we can use execute() that has less side effects than :redir. But we can also simply use filter() on getreg() results. See my answer. – Luc Hermitte Apr 9 at 14:52
  • @LucHermitte, I edited my function. Could you take a look and see if it's okay? Also, why would execute() be better than redir? Except of course easier to use. – klaus Apr 9 at 15:04
  • 1
    It relates to silencing the execution. Also setline() can take a list, or there is simply :put= – Luc Hermitte Apr 9 at 15:11
  • @LucHermitte, I edited again. Is this alright? Sorry for bothering you. – klaus Apr 9 at 16:07
  • 1
    If it gives the right result, then this is alright :) We can always add more. For instance, my scratch buffers are also usually readonly, they have a name that starts with pluginfeaturename://, and I can dismiss them with q. Others will be perfectly happy with new or vnew and so on. – Luc Hermitte Apr 9 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.