1

I want to call g@ from a function.

Given an operation:

" Taken from :help g@
function! CountSpaces(type, ...)
  let sel_save = &selection
  let &selection = "inclusive"
  let reg_save = @@

  if a:0  " Invoked from Visual mode, use gv command.
    silent exe "normal! gvy"
  elseif a:type == 'line'
    silent exe "normal! '[V']y"
  else
    silent exe "normal! `[v`]y"
  endif

  echomsg strlen(substitute(@@, '[^ ]', '', 'g'))

  let &selection = sel_save
  let @@ = reg_save
endfunction

I want to call it from:

function! my_fun(...)
        set opfunc=CountSpaces
        normal! g@
endfunction

But it doesn't work, nothing happens. Am I doing something wrong?

  • Normally, this is done from a mapping, though I don’t see why it shouldnt work. Do note that my_fun probably needs an uppercase start – D. Ben Knoble Oct 9 at 12:53
  • 1
    g@ needs a motion. Therefore normal! g@ does nothing. (But, for example, normal! g@$ will work). – Matt Oct 9 at 12:58
3

The g@ must be used with a motion, so it effectively switches to the operator-pending mode. However, that will not work in your example.

From :h :normal:

{commands} should be a complete command.  If
{commands} does not finish a command, the last one
will be aborted as if <Esc> or <C-C> was typed.

So eventually normal! g@ ends the operator-pending mode and falls back into the normal mode. Hence g@ does just nothing.

Simply supplying any motion will work (e.g. normal! g@$), but it's almost useless, as normally we want an operator, not a fixed operation. That's the reason g@ should be invoked by a mapping, like in :h g@.

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.