New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[proposal] built-in space for plugins configuration (vim.config) #22665
Conversation
Thanks for making the effort to propose this, but I don't really see why this is something that needs new code in Neovim. Plugins very deliberately can do whatever they want, and we do not want to constrain that; it is up to the ecosystem to come up with best practices and share them. Note that plugins can do very different things, and what makes sense for some will make no sense for others; centralizing -- and ossifying! -- one particular approach is not helpful. Also, your premise is flawed: Finally, there really is no way of a guaranteed "resetting" of a plugin short of restarting Nvim, and implying that by providing such a function is actively harmful. |
Nicely done, very constructive. We've rejected similar idea in the past #9517 #8677 cc @KillTheMule . In those cases and this one, main question is which of these actually are valuable as formal interfaces: can we get 80% of the way by (first) providing guidance #22366 ? A counterargument is
My sense is that these kinds of "standard" interfaces can be very useful, but we may be able to skip the "active registration", in favor of "passive discovery": e.g. if
|
This is what plugins should do, it isn't a hassle, and overall results in a more robust plugin. We aim to provide better guidance on how to achieve this (#22366). |
If there is no interest in having a interface for plugins, this is obviously useless, but I'll answer to the objections.
What the ecosystem came up with (the
The kind of argumentation that I care zero about. I don't want to rely on package managers to have a sane configuration.
This system makes no guarantees. It provides an interface for plugins that want to implement this functionality, in a way that users and plugin authors don't have to think much about how to expose the functionality (or use it), and also in a way that you can know (with the popup) if a plugin supports that functionality or not.
There is a fundamental problem, that if the configurations aren't stored in a centralized place, where plugins can fetch them without being sourced, lazy-loading becomes difficult, and in any case not complete, even in the case that authors isolate the setup process in their plugins. Other than this, other approaches can work, but this was my main motivation.
These extra features I added last, because I thought they could be useful once a centralized place was there. Of course there are other ways.
I mostly thought about mappings being unmapped and such, not actually removing a plugin altogether, that would be dangerous. Edit:
Added only because possible, not sure how it can really be useful. I don't think there are many cases where a plugin wants to inquire some other plugin configuration.
I thought it as a way to avoid to use
It doesn't solve all problems. Some plugins have dependencies, if you want to correctly load the plugin with a dependency, you must fully load the dependency, and they can be big like telescope and such. Simply put, the |
Anyway I'm closing this since it's not a real PR, just a proposal. |
You're assuming that lazy-loading is a widely accepted and recommended way of handling plugins. It isn't! We have |
@mg979 This is definitely appreciated because it advances the conversation around this topic and is a great reference. So thanks again.
|
What annoys me is that you can easily lazy-load a plugin if you don't want to change any configuration options, otherwise you must load it. And that if you want to lazy-load it, you must do everything by yourself, setting up autocommands, wrappers, and even fight with the plugin itself when it assumes that its
It was in vim. Anyway, this was a proposal, not a way to be polemic with the currently accepted convention. Today |
You will save yourself a tonne of time by simply not lazy loading. If there's a plugin that is slowing down your startup, then raise an issue on said plugin, or simply don't use it and find a better alternative. |
I'm the developer of a plugin that uses the setup style, but I don't see much benefit from the setup style. (It simply adopts ecosystem conventions.) The vim.g/vim.bo style doesn't have lazy loading issues, it's a convention from vim days, and I think it's a simple solution. I myself use vim like this:
I agree with the concern that the ecosystem is currently in confusing. google translated |
I don't do that (wrappers and such, tired of that madness). I only meant that you'd need to do it if you wanted lazy load stuff. |
@mg979 I am sympathetic to all of the points you've raised. I too find the commonly used Just to clarify terms here, I think of "lazy loading" as "loading on demand", a feature which Vim has supported for quite some time through autoloaded functions. I think this is a great feature and plugins should be written in a way to take advantage of this (as Vim plugins have been for many years). Essentially, a plugin should load as little code as possible at Nvim startup, and defer loading the rest of its code until it's actually needed. The use of a However, this need not be the case. A Lua plugin is really not much different than a Vim plugin: instead of Vimscript functions in an The fundamental issue is not, in my opinion, a deficiency in support from Neovim core, but rather a lack of guidance or awareness of these patterns in the broader plugin community, which #22366 is (in part) meant to address. There is one part of your proposal that I found very compelling though, which was the |
This was something we discussed in the context of "plugin specifications", where I always argued that such a specification should contain an "API manifest" listing
(I also argued that plugins should not define mappings themselves, and especially not for something that isn't listed in the manifest.) But again, I think that this is the proper level of handling that (which may lead to something similar in core, but less ad hoc). |
This is essentially what I've been trying to say. In theory, plugins could separate the 'gather configuration' part, from the actual initialization part. User calls
I think at least |
Not sure we need a manifest. We have the |
To add my 2 cents:
|
This is a proposal for a built-in common place where plugin configurations are stored and accessed (in a safe way).
Not a real PR, but you can read the code.
The currently adopted convention is to have lua plugins to call a
setup()
function. This has the advantage that it doesn't require setting options in a global variable (typicallyvim.g
), but has the disadvantage that it prevents proper lazy loading, sincerequire
-ing the setup functions in many cases will source most of the plugin scripts: impossible to lazy-load the plugin at that point, unless the plugin author has care to isolate the setup process from the rest of the plugin. I don't think many do this, and it's a hassle in itself, while setting up plugins should be hassle-free.Since Vim (and therefore Neovim) have had means for package lazy-loading for years now, I don't think there are good excuses for plugins to prevent the users from correctly loading them at a convenient time, and not before that.
This is an alternative system that has the following advantages:
How it works? Assuming that the functionality resides in
vim.config
.All tables are protected so it's not possible to mess up the configurations.
What the user does
The user configures plugins like this:
This simple. Note that it's actually a function call. If you try to do:
it's an error.
When this is done the first time (in the user vimrc), the plugin isn't loaded yet. It will load when it thinks it should. Or maybe it will never be loaded, who knows at this point.
Plugin configuration can be later updated in the same manner. Doing so, will not replace the configuration, will only update it with the new values. To completely replace previous configuration, add
true
argument:If a setup function has been set in the meanwhile, it will be called.
What the plugin author does
The plugin can fetch its own user configuration with:
It can set a
setup
function, so that if the user wants to adjust the options, the setup function will be called automatically:Next time the user does:
that call will not only update the configuration, but also call the setup function, and the plugin can update its configuration (will get the user option directly from
vim.config
).There are other functionalities that a plugin can enable:
Where:
plugin_reset_func
can be used to reset plugin options to their default value, and the user configuration will be cleared.plugin_query_func
can be used to query the plugin for any current option, or all options.plugin_enable_func
can be used to disable/re-enable a plugin.Of course these functionalities would have to be provided by the plugin, it's not that a plugin can be disabled/re-enabled automatically, or that
vim.config
can know about internal plugin configurations.They are all optional anyway, so nobody would have to be obliged to implement them all (even if a
setup
function at least would be recommended, so that plugin configuration can be updated).Checking plugin state
When a plugin is loaded, it should call in its initialization process:
That means: set the
loaded
state as true. Other plugins can check the state with:Note: having for this a table like
vim.loaded
orvim.plugin.loaded
would be probably better.Similarly, if a plugin has a
disable/enable
functionality, a plugin can be disabled with:Re-enabled with:
Check the
enabled
state with:Note: having for this a table like
vim.enabled
orvim.plugin.enabled
would be probably better.Displaying configurations
Will open a popup window with all configured plugins, telling if it's enabled or not, when it's been updated and in which file, also telling with which options it has been configured each time (for debugging purposes).
It will tell which other functionalities the plugin implements.
Example: