2

This is just my own curiosity speaking here, but would it be possible (if it's even possible by default in normal vim, without any additional plugins etc) to call a function inside a vimscript function without having to use call?

I'm thinking of emulating or doing things like when special function/keywords like echo and other builtin are called:

function! Test()
echo something
endfunction

above we can see we do not need to use call to run echo. Would it be possible to do the same on a function we make ourselves? eg: replace echo above with Myfunction but without having to use call.

To make myself more clear: I already know this is possible for function defined as commandline or user defined commands, where one can just do :Myfunction in Ex mode, but that isn't what I want to do, although it is similar in that it does not need the use of call.

P.S: While I mentioned earlier wanting to know if it's possible in normal vim (eg: without plugins etc) I wouldn't mind knowing if it's still possible using plugins either, but the main point here is still knowing if it's possible without them.

4
  • 2
    Functions and Ex commands are different namespaces in Vim. echo works without call because it's an Ex command and not a function. You can define functions, that you then can use with :call or :eval or within Vimscript expressions (for example, as arguments to :echo or to :let). You can define new Ex commands as user-defined commands (though with the restriction they need to start with uppercase.) So you can either use :call on functions, or create a user-defined command, either would accomplish what you're asking here...
    – filbranden
    Mar 14, 2022 at 16:52
  • 1
    @filbranden Thanks for the added clarification -- noticed statox's answer works, so that was just me misunderstanding. :D Mar 14, 2022 at 16:59
  • 1
    It relates to the need to distinguish ex-commands from function calls. There are a few overlaps like :substitute and substitute(), insert... vi.stackexchange.com/questions/19142/… Mar 15, 2022 at 11:23
  • didn't find this when I searched. Nice :D It does explain things further as to why it is the way it is. @LucHermitte Mar 15, 2022 at 11:40

2 Answers 2

4

I'm not sure why you would need that in this context but you could use a user defined command (:h user-commands):

function MyFunction(argument)
    echo a:argument
endfunction

command! -nargs=1 Myfunc call MyFunction(<args>)

With this you can use :Myfunc "hello" from the command line and you will get the result of echo "hello", this is the most common use of user defined commands.

But it also means that you can use that in any vimscript file.

There is a lot to read about how to use these :h :command-completion,:h :command-nargs, :h :command-range...

7
  • I know how to make user defined command, and I also know how to do it like you did here so that I don't need to use call on the commandline...but my question was to do this but for function outside of commandline :) Mar 14, 2022 at 14:47
  • basically, following your answer, instead of doing :Myfunc "hello" I want to know how to do Myfunc "hello" inside a vimscript function outside of commandline (eg: without having to do call Myfunc "hello" when using it inside a function) Mar 14, 2022 at 14:48
  • 2
    I understand and that's why 1) I said I don't see why you would need to do that: I don't see any advantage to have two different ways to call the same function in a piece of code. In the command line I understand that shortness is an advantage but not in code. 2) I suggested that you use commands because that is the probably the only solution you have to call a function without the keyword call
    – statox
    Mar 14, 2022 at 14:53
  • 2
    I see. that's understandable :) I appreciate the effort to convey that which is why I upvoted it, but if there isn't any way to do this, I guess that still good to know. Mar 14, 2022 at 14:55
  • 2
    I still think it's a big anti-pattern and you should not do that until you have a very good reason because all it does is adding an unnecessary level of indirection in your code. But it's great that it answers your question :)
    – statox
    Mar 14, 2022 at 17:05
2

Oh, well. It is absolutely not about "call". It is about command-line mode (or sourcing a script which is almost the same thing).

In command-line mode everything must start with a command. It could be call foo() or eval foo() or let xyz = foo() or thousand of other constructs. But they all start with a command that accepts an expression. Not with function name (i.e. expression itself). So easy.

7
  • please, reread my edited post. I'm well aware it's possible on commandline mode or Ex mode -- my question was about doing this inside a function in vimscript outside commandline mode (eg: inside a .vimrc for example) Mar 14, 2022 at 15:05
  • @NordineLotfi Re-read my answer. It is almost the same thing.
    – Matt
    Mar 14, 2022 at 15:06
  • @NordineLotfi People seem always to miss this. VimScript is much like shell scripting: there's only marginal difference between "interactive" and "script" modes.
    – Matt
    Mar 14, 2022 at 15:09
  • I re-read it many times, but to me it isn't almost the same thing :/ you're essentially saying "they all need to start with a command that accept an expression", but I already know that (and also doesn't apply when one is doing user defined commands which is also not what I want to do) Mar 14, 2022 at 15:12
  • 3
    Vimscript is a collection of Ex commands. As a Vim function is not an Ex command, you need to use the ":call" Ex command to invoke the function. Note that in a Vim9script, this has been addressed and you can invoke a function without using ":call". Mar 14, 2022 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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