0

I have a function:

function myPlugin#myFunc()
  " ....
  enew
  termopen(['cmd', 'here'], termopen_opts)
endfunction

And in my plugin/myPlugin.vim I do:

nnoremap <expr> <leader>e myPlugin#myFunc()

But when I press <leader>e I get:

Error detected while processing function myPlugin#myFunc:
line   41:
E523: Not allowed here:     enew

But if I put in plugin/myPlugin.vim:

command! -nargs=+ MYCMD call myPlugin#myFunc()
nnoremap <leader>e :MYCMD<CR>

I don't get the error and enew does it's job. Any idea why?

  • Also, IIRC, you cannot have a function call as an ex command on its own (termopen...). You could echo, call, or return it, for just a few options, as those are ex commands – D. Ben Knoble Jun 11 at 11:50
  • What you can do, is make your function return the commands that need to be executed, e.g. return ":enew\<cr>:call termopen...." – Christian Brabandt Jun 11 at 12:15
2

There are limitations in things you can do in a function called from a map-expression.

From the docs:

Be very careful about side effects!  The expression is evaluated while
obtaining characters, you may very well make the command dysfunctional.
For this reason the following is blocked:
- Changing the buffer text |textlock|.
- Editing another buffer.
- The |:normal| command.
- Moving the cursor is allowed, but it is restored afterwards.
If you want the mapping to do any of these let the returned characters do
that.

And :enew wants to edit another (new) buffer.

See :h map-expression.

Try this:

nnoremap <leader>e :call myPlugin#myFunc()<cr>
| improve this answer | |

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.