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 Answers
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 [])– IvanDiApr 10, 2019 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. Apr 10, 2019 at 12:29 -
Now it is ok, the problem was that
filter
destroys theregs
variable and therefore the list with the register names must be generated every time before calling thefilter
. Thanks!– IvanDiApr 10, 2019 at 13:15 -
Oh. Yes indeed. The other possibility in those cases is to
copy(res)
infilter()
call. Apr 10, 2019 at 13:44
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 knownsplit(..., "\n")
split into a list of linesfilter(..., {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.
-
1Note, 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 Apr 9, 2019 at 17:26
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.
-
1Now we can use
execute()
that has less side effects than:redir
. But we can also simply usefilter()
ongetreg()
results. See my answer. Apr 9, 2019 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.– 3N4NApr 9, 2019 at 15:04
-
1It relates to silencing the execution. Also
setline()
can take a list, or there is simply:put=
Apr 9, 2019 at 15:11 -
-
1If 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 withpluginfeaturename://
, and I can dismiss them withq
. Others will be perfectly happy withnew
orvnew
and so on. Apr 9, 2019 at 16:54