1

I want to count the searching pattern and here is my code:

execute '%s/' <C-R>/ '/\=' . Count(submatch(0)) . '/gn'

Here is my Count function:

function! Count(match)
  if has_key(b:types, a:match)
      let b:types[a:match]+=1
  else
      let b:types[a:match]=1
  endif
  return a:match
endfu

I borrowed the function from this answer by Christian Brabandt.

I have tried the following option to combine the searching part <C-R>/ and the function calling part Count(submatch(0)) and the rest but all cannot work:

execute '%s/' . <C-R>/ . '/\=' . Count(submatch(0)) . '/gn'

And I have read the help document by entering :help execute and this tutorial.

Any suggestions would be very appreciated. Thanks in advance.

  • 3
    why you need <c-r>/, doesn't that do what you want: %s//\=Count(submatch(0))/gn – Christian Brabandt Nov 22 '19 at 22:11
  • I want to match the strings I was previously searching for. – Lerner Zhang Nov 23 '19 at 10:01
  • 2
    @LernerZhang thats what an empty pattern does – D. Ben Knoble Nov 23 '19 at 17:15
1

You're mixing up a few concepts...

You can use <C-R> from Insert or Command-line mode (when typing an Ex command after entering it with a :) to insert the literal contents of a register. (See :help c_CTRL-R.)

So you can use that in a direct mapping (without the indirection of :execute), like so:

nnoremap <Leader>c :%s/<C-R>//\=Count(submatch(0))/gn<CR>

When this mapping gets executed (with <Leader>c, which defaults to \c if you haven't set mapleader), the <C-R>/ sequence will expand to the contents of the search register and will be inserted as part of the Ex command.

If, instead, you want to use :execute (because you're not in the context of a mapping, for instance you're inside a function), then what you need is to assemble a string with the full command you want to execute.

In that case, you want to use @/, which returns the contents of the search register as a string, that you can use as part of an expression. (See :help expression-syntax, which has an entry for @r that evaluates to "contents of register r.")

Another issue with your attempt is that you had Count() as a function call, but you actually want it to be part of the string, since it's only supposed to be evaluated by the \= in the replacement of the :substitute command.

Putting it all together:

execute '%s/'.@/.'/\=Count(submatch(0))/gn'

Finally, as pointed out in this comment from Christian Brabandt, in this particular case you don't need to expand the search register at all, since if you use a :substitute command without a pattern (empty pattern), the last searched pattern will be used instead. So you don't actually need <C-R>/, @/ or execute at all, all you need is:

%s//\=Count(submatch(0))/gn

In a function, this command will work directly (it's a valid Ex command.) In a mapping, all you need is to prepend : and add a <CR> at the end. Pretty straightforward!

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.