-
-
Notifications
You must be signed in to change notification settings - Fork 43
feat!: lazy auto setup #175
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
base: main
Are you sure you want to change the base?
Conversation
return config | ||
end | ||
|
||
local current_config = build_config(M.schema) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build the config once to be able to just deep_extend
the user_config into the current config. This should make it possible to call setup multiple times without having any side effects on the users config option
|
||
core.update() | ||
state.cfg.on_attach(util.current_buf()) | ||
state.cfg.on_attach(require("crates.util").current_buf()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lazy require the util
module until it is actually needed
|
||
vim.api.nvim_create_autocmd("BufRead", { | ||
pattern = "Cargo.toml", | ||
once = true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create an autocmd that is fired once upon the first entry in a Cargo.toml
file. This shouldn't change any option in case users have setup the plugin before this. Also, if the user calls setup after this, it should properly update the options accordingly
Improves setup time with a couple of milliseconds :)
@@ -1,41 +1,37 @@ | |||
local actions = require("crates.actions") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline these wrapped around a function to lazily require the modules😅 This seems to be improve the setup time from around 3ms to 0.5 ish for me
This is now handled by the plugin itself, so no need for users to lazy load themselves
Hey, thanks for this PR! I'll have to give this some thought. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one thing I've noticed.
local config = build_config(M.schema, user_config) | ||
if config.neoconf.enabled then | ||
return setup_neoconf(config) | ||
current_config = vim.tbl_deep_extend("force", current_config, user_config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fail in some cases. For example if a scalar is provided by the user instead of a table, the config will now be invalid, because the default table will be overwritten.
Also unless I'm forgetting something the user config was never mutated to begin with, or did you hit some case where calling setup
wasn't idempotent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fail in some cases. For example if a scalar is provided by the user instead of a table, the config will now be invalid, because the default table will be overwritten.
A few lines above it ensures that the user_config
is a table, so I don't think that should be a problem
Also unless I'm forgetting something the user config was never mutated to begin with, or did you hit some case where calling setup wasn't idempotent?
The reason I changed it was because if calling setup once with for example { smart_insert = false }
, and then again calling setup with {}
, I would prefer it to still be { smart_insert = false }
. This was not the case because build_config
always preferred the default value over any missing values in the user provided config, and did not take into account the potential previous call to setup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few lines above it ensures that the
user_config
is a table, so I don't think that should be a problem
I was talking about a nested table so for example { lsp = true }
would overwrite the complete lsp
configuration table.
The reason I changed it was because if calling setup once with for example
{ smart_insert = false }
, and then again calling setup with{}
, I would prefer it to still be{ smart_insert = false }
. This was not the case becausebuild_config
always preferred the default value over any missing values in the user provided config, and did not take into account the potential previous call to setup
Oh, I see. Maybe we could just extend the previous config before passing it into the build_config
function. That way the config is still validated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was talking about a nested table so for example { lsp = true } would overwrite the complete lsp configuration table.
Hmm good point. It should still use the default value in this case like the warning is saying that it does? Another option (maybe a bit hard) would be to just error instead of giving a warning
Oh, I see. Maybe we could just extend the previous config before passing it into the build_config function. That way the config is still validated.
Yeah I was thinking about that as well, but that would give a lot of warning about the user using deprecated options etc since the user_config is now the full config instead of only what the user provided🤔
I generally agree with this myself, but thought maybe it would make sense for this plugin
Interesting. Can you elaborate on why you don't necessarily like automatic setup? I didn't previously give the widely adopted setup function much thought, but I have been thinking about this a bit lately, and I very much agree with the documentation in neovim now discouraging that when there is no required settings to set for the plugin to work. With lazy.nvim I can see that it generally is not so annoying to just add a vim.pack.add({
"https://github.com/saecki/crates.nvim",
})
require("crates").setup({}) instead of just doing this vim.pack.add({
"https://github.com/saecki/crates.nvim",
}) when I am perfectly happy with the default options this plugin provides |
I just had cases where I wanted to do some stuff before a plugin ran it's setup. Granted some of those we're hacky things, but the automatic setup was kind of in the way. |
Wouldn't it be possible to either just use
It can be debated the other way around as well. I don't see why I have to refer to the plugin in multiple places if the plugin doesn't require any options to work
Yes but it's really not that much work No problem if you don't want this. I am just looking to migrate to |
Problem:
The user is required to call setup() even if they are perfectly happy with the default options. Also, requiring every user to lazy load is annoying, and also requires that the plugin manager the user is using is supporting this out of the box
Solution:
Make setup optional, and lazy load the plugin automatically
Context:
Neovim has recently added some documentation of developing a lua plugin with some "best practices" https://github.com/neovim/neovim/blob/master/runtime/doc/lua-plugin.txt
In the Initialization section, it is recommended to allow users to opt out of calling setup if the default options are working perfectly fine. For me they are working perfectly fine, and I agree that calling setup is unnecessary in this case.
They also have a section talking about lazy loading, and making a case for this to be handled by the plugin instead of the user themselves. I agree with this, and saw a good potential to automatically do it here😄