2

In :help vim9 I read

The Vim9 script syntax and semantics are used in:

  • a function defined with the :def command
  • a script file where the first command is vim9script
  • an autocommand defined in the context of the above
  • a command prefixed with the vim9cmd command modifier

Seems easy to read, but I can't get much stuff working.

Attempt 1

I've created a file.vim with this content:

def! FunWithDef(n: number): number
  return n * 2
enddef

and then run :so % after writing it. Afterward, I can run :echo FunWithDef(3) and get back 6. So far so good.

Attempt 2

In :help vim9-reload I read

When loading a Vim9 script a second time all existing script-local functions and variables are deleted, thus you start with a clean slate.

However, if I change the name of the function above and run :so %, I can still run the function via the old name (and the new one as well, obviously). Why is that?

Attempt 3

If I add a line containing just vim9script at the to of the script above, when I try to :so %, I get E477: No ! allowed. Why is that?

Attempt 4

If I remove the "erroneous" vim9script, and define the following instead,

var FunWithLambda = (x) => x * 2

then, upon :so %, I get E1124: ":var" cannot be used in legacy Vim script, but I can't add a vim9script line, as per the previous attempt.

Attempt 5

But I can try prepending vim9cmd to the definition of the lambda,

vim9cmd var FunWithLambda = (x) => x * 2

which makes :so % succeed, but trying to call :echo FunWithLambda(3) fails with E117: Unknown function: FunWithLambda (I can't tab-complete FunWithLambda, indeed). Prepending :vim9cmd to echo doesn't change anything.

2
  • I'm not convinced of the need for new tags for all the vim9script specific commands. But feel free to discuss on Vi and Vim Meta.
    – D. Ben Knoble
    Commented Feb 17, 2022 at 18:15
  • Ok.
    – Enlico
    Commented Feb 17, 2022 at 18:29

1 Answer 1

2

In vim9script def should be without !. Not sure if def! should be allowed in legacy vimscript.

All functions in vim9script are script local by default unless you export them or explicitly use g: as in def g:SomeFunction().

Attempt 1

This is clear

Attempt 2

You are reloading legacy vimscript which is defining "new style" function. In this case function is defined globally, so if you change the name and reload a file a new function is defined but previous global is still available with the old name.

Attempt 3

If you add vim9script then def! is not allowed for script-local functions as it doesn't make sense because they can't be redefined. See :h E1117.

Note, you can use def! g:SomeFunc() <-- global function.

Attempt 4

This should be clear, var is available only if your script is vim9script.

Attempt 5

With

vim9cmd var FunWithLambda = (x) => x * 2

you have defined a script local variable, you could call it with, for example:

vim9cmd var FunWithLambda = (x) => x * 2
vim9cmd echomsg FunWithLambda(10)

And yes it wouldn't be available in "tab-complete".

So

How can I define vim9 functions and vim9 lambdas in a vim9 script?

Like this:

vim9script

# global func, available in cmdline :echo FunWithDef(2)<CR>
def g:FunWithDef(n: number): number
  return n * 2
enddef

# global lambda, available in cmdline :echo FunWithLambda(2)<CR>
g:FunWithLambda = (x) => x * 2

# local func, available in this script
def FunWithDef2(n: number): number
  return n * 2
enddef

echom FunWithDef2(10)

# local lambda, available in this script
var FunWithLambda2 = (x) => x * 2

echom FunWithLambda2(20)
6
  • :help :def reads [!] is used as with :function. Should I assume that the doc is simply not up-to-date?
    – Enlico
    Commented Feb 17, 2022 at 8:07
  • 1
    @Enlico idk, I have asked in vim_dev: groups.google.com/g/vim_dev/c/i0oQNlsL_cM
    – Maxim Kim
    Commented Feb 17, 2022 at 8:08
  • TBH, I don't understand how I can apply Bram's to solve the doubts in my question.
    – Enlico
    Commented Feb 17, 2022 at 18:33
  • @Enlico see update
    – Maxim Kim
    Commented Feb 17, 2022 at 18:59
  • The "!" for the ":def" function is needed only in a legacy script (and not in a Vim9 script) to override an existing function definition. The "!" is needed only if the same function is defined in two different scripts. If you want to try using Vim9 constructs, I will recommend starting the script with the "vim9script" statement and not mix legacy and Vim9 constructs. Commented Feb 17, 2022 at 20:19

Your Answer

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

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