Create ~/vimfiles/autoload/x.vim with the following content:
vim9script
export enum Fruit
Banana,
Apple
endenum
If you source it twice, then you get E1041.
If you move away the script from autoload folders, then you can source it as many way as you want.
It should be possible to source the script as many times as user want without throwing any error.
9.1-1942
Win 11
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
This seems working as expected.
Files under autoload/ update the loaded information for the file path name (x in this case) the first time they are loaded.
The first time :so is used, the loaded information for the file path name (x) is internally updated to indicate that it has been loaded, but the second time :so is used, the file has already been loaded, resulting in an E1041 error.
Normally, Vim9 scripts use import autoload for the autoload mechanism.
This allows control that loads only the first time to work correctly.
vim9script import autoload 'x.vim' var f = x#Fruit.Banana echo $"f: {f.name}"
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan What is your take on this?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
So what is the point of having noclear and why moving scripts in another folder won't suffer the same problem. The current behavior is cumbersome in vim9 context.
I could understand such a behavior in legacy-vim (and for every script), but definitely not in Vin9.
In vim9 you have noclear if you really want such a behavior.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Normal def functions can be redefined, but since enum/class are part of the type system, I believe redefining them is prohibited due to compatibility issues with existing instances.
I think you should either use import autoload, or define export enum and export class outside of autoload/.
If you are developing a plugin and have made changes to autoload/x.vim, restart Vim.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Document says:
Reloading a Vim9 script clears functions and variables by default
In other words, nothing other than functions and variables will be cleared.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@yegappan Is this the final decision? I don't think 'autoload' dir is very special. If you suggest to develop vimclass or enum in different directory, could you please point it out in the document?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
In other words, nothing other than functions and variables will be cleared.
In fact, only functions can now be cleard for files under autoload/. Variables still have this problem for both var and const.
vim9script
export def F()
enddef
export var a = ''
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Thanks for the follow-up. There are two separate cases here.
An exported item of an autoload script lives in the global namespace with the
autoload prefix (e.g. x#a). On reload the script-local items are cleared but
these globals were not, so a second :source of an exported var/const hit
the redefine guard (E1041). Functions were already replaced on reload; that is
the asymmetry you noted.
The PR gives exported var/const the same clean slate as functions, so an
autoload script can be sourced more than once. The new definition wins (value
and type), and a genuine duplicate within one script still errors.
These stay E1041. A reloaded class or enum cannot update objects created from
the old definition (they keep it via reference counting), so only new instances
would see the change. Forcing a restart is more honest than a half-applied
reload.
This is a behaviour choice, not a safety limit: allowing it does not crash or
corrupt memory (member access is checked against each object's own class).
Whether to relax it for an unchanged reload is a design question better settled
with the class/enum owners, so the PR keeps the current behaviour.
The supported way to use an autoload script is import autoload, which loads it
once and never hits this. For a changed class or enum, restarting Vim remains
the reliable approach.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
@chrisbra as the accepted solution of this issue is cf80f13, then at bare minimum the documentation of autoload shall be updated with something like the following:
... when a script is in
autoload/folder andnoclearis not specified in the script, then sourcing such script leaves vim in a hybrid state where variables, constants and functions are cleared but enum and classes retain the previous state. To clean enum and classes you must close and re-open vim.However, sourcing a script located in any other folder than
autoload/has the following effect:
- If
noclearis specified, then variables, constants, functions classes and enum retain the previous state,- If
noclearis not specified, then variables, constants, functions classes and enum are cleared,thus leaving Vim in a consistency state. There is no need to close and re-open vim.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Thanks, I'll update it slightly to mention the autoload folder
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Thanks. I was reflecting why exported class/enums cannot be redefined if located in autoload/ but can be redefined if located in any other folder, e.g. lib/ given that from the docs it is not very clear and such a behavior looks fairly inconsistent.
I may be wrong, but I think the reason may be due to the induced scope when sourcing items from autoload/ and when sourcing from any other place. I try to explain better below.
Say that I have a script my_script.vim that includes the following snippet:
export enum Color White, Red, Green, Blue, Black endenum
If I source autoload/my_script.vim, then the enum Color goes in the global namespace. Hence, once I source again the script, Vim already find it defined in the global namespace and return error.
On the other hand, if I source lib/my_script.vim, then then the enum Color is kept script-local.
Next, if in foo.vim I add the following code:
import autoload '../lib/my_script'
then enum Color won't become global, despite of the keyword autoload.
In-fact, such an autoload keyword only indicates a lazy loading and should have nothing to do with the autoload keyword used to indicate the autoload/ folder (in-fact, I would have used another keyword e.g. lazyload and use that one e.g. import lazyload '../lib/my_script.vim').
With import autoload '../lib/my_script the enum Color retain its script-local sope!
This is the reason why you can source lib/my_script.vim over and over with no problems: simply because enum Color is not found in the global namespace!
I am not sure if I get it right, @h-east or @chrisbra may confirm, because from the docs it is difficult to deduct it.
If the above explanation is correct, perhaps it should be clarified in the docs, and, less important, I would definitely avoid the autoload/ like the plague for my plugins in the future.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Your understanding is correct, including the key point that lazy loading and the
autoload/ folder are two separate things.
To put the mechanism precisely: a script is an "autoload script" purely by its
path. If the path contains /autoload/, Vim derives a prefix dir#script# from
the file name and registers every exported item in the global namespace under
it (e.g. my_script#Color), the same convention as foo#bar() autoload
functions. On a re-source, var/const are cleared and redefined, but classes
and enums are intentionally kept (existing instances still point at the old
definition, so Vim asks for a restart instead of a half-updated state), which is
why you get E1041. A script not under /autoload/ gets no prefix, its items
stay script-local, and re-sourcing works. This depends only on the path, so even
a direct :source autoload/x.vim globalizes.
import autoload is the separate axis: it just means "load lazily," so
import autoload '../lib/x.vim' outside autoload/ is still deferred, not an
eager import. The only nuance to "nothing to do with the autoload folder" is
that a bare name like import autoload 'for/search.vim' does look in the
autoload/ directories of 'runtimepath'; a relative or absolute path detaches
the two completely.
Agreed the docs could make the path-based prefixing and its effect on
re-sourcing clearer.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()