You can easily reference closure from autocmd_add() cmd key. As example
function! s:Foo() abort function! s:Bar() closure echom 'foobar' endfunction call autocmd_add([#{event: 'CursorMoved', pattern: '*', cmd: 'call s:Bar()'}]) endfunction call s:Foo()
How to achieve the same with vim9? Tested a lot of the things without any success.
vim9script
def Foo()
def Bar()
echom 'foobar'
enddef
autocmd_add([{event: 'CursorMoved', pattern: '*', cmd: 'Bar()'}])
enddef
Foo()
Error detected while processing CursorMoved Autocommands for "*": E117: Unknown function: Bar
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
How about this? This worked at least in my environment.
Runned steps:
vim --clean:%sovim9script var BarRef: func(): void def Foo() const baz = 'baz' def Bar() echom 'foobar' .. baz enddef BarRef = Bar autocmd_add([{event: 'CursorMoved', pattern: '*', cmd: 'BarRef()'}]) enddef Foo() doautocmd CursorMoved # => foobarbaz
Environment:
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Maybe :h E1058 is related to this:
When using `:function` or `:def` to specify a nested function inside a `:def`
function and no namespace was given, this nested function is local to the code
block it is defined in. It cannot be used in `function()` with a string
argument, pass the function reference itself: >
def Outer()
def Inner()
echo 'inner'
enddef
var Fok = function(Inner) # OK
var Fbad = function('Inner') # does not work
Detail: this is because "Inner" will actually become a function reference to a
function with a generated name.
It is not possible to define a script-local function in a function. You can
define a local function and assign it to a script-local funcref (it must have
been declared at the script level). It is possible to define a global
function by using the "g:" prefix.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
And now Bar isn't local at all
I have simplified the example. This is working yes, but now try this
var BarRef: func(): void
def Foo(boo: string)
const baz = 'baz'
def Bar()
echom $'foobar{baz}{boo}'
enddef
BarRef = Bar
autocmd_add([{event: 'CursorMoved', pattern: '*', cmd: 'BarRef()'}])
enddef
Foo('moo')
Foo('boo')
moo is overriden by boo
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Ok i have tried legacy script version and i doesn't work too :(
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Any workaround to achieve what I want? Dynamically create autocommands?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I came up with two workarounds, but both of this is not good at managing added autocmds...
vim9script var BarRefs: list<func(): void>
def Foo(boo: string) const baz = 'baz' def Bar() echom $'foobar{baz}{boo}' enddef
BarRefs->add(Bar) enddef def OnCursorMoved() for F in BarRefs F() endfor enddef autocmd_add([{event: 'CursorMoved', pattern: '*', cmd: 'OnCursorMoved()'}])
Foo('moo') Foo('boo')
vim9script def Bar(baz: string, boo: string)
echom $'foobar{baz}{boo}' enddef
def Foo(boo: string) const baz = 'baz'
autocmd_add([{event: 'CursorMoved', pattern: '*', cmd: printf('call("Bar", %s)', [baz, boo])}])
enddef Foo('moo') Foo('boo')
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@mityu Thank You. Will test if any of those works for my needs and then will report.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Ok I did something similar to you first suggestion and it works, too bad that there is no simpler solution, that do not require some dangling list/dict. I will leave this open for a few days, maybe someone would suggest something better. Thank You nevertheless.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Thank you, Bram.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Closed #11870 as completed.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I think it would be neat to allow a funcref in autocmd_add and add a callback_T cmd_cb field to the auto command struct for it. The same would be nice for options like omnifunc. Interestingly these are stored into the buffer structure as callback objects but only set as strings.
I started working on a patch to allow a funcref as the cmd option in autocmd_add but ran into a conceptual limitation: these places cannot be extended to hold funcrefs without slightly breaking compatibility. There are potentially scripts that rely on the fact that these values are accessed as strings. Now the common pattern of saving an option value and then restoring it should work the same (except if it is a vim9 script that is using the string type for the variable) and autocmd_get is only since vim9 so maybe this slight incompatibility is acceptable.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I think it would be neat to allow a funcref in autocmd_add and add a callback_T cmd_cb field to the auto command struct for it.
The same would be nice for options like omnifunc. Interestingly these are stored into the buffer structure as callback objects but only set as strings.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()