I'm really looking forward to this. I hope it helps push the nvim plugin community into lazy loading plugins by default instead of relying on a complex plugin manager like lazy. The nvim docs have a little note related to this[1].
I'm quite a fan of the nvim-neorocks plugin best practices as well[2]. In fact it seems like part of them got merged recently[3] hahaha.
[1] https://neovim.io/doc/user/lua-plugin.html#lua-plugin-lazy
The neovim model of using setup() makes lazy loading a bit trickier than traditional Vim.
Lazy loading is much easier with Vim’s model of configuring by setting variables. You just set variables in init.vim, and the plugin can auto-load when one of its functions is executed.
With lua this requires more orchestration; if many autocmd refer to the same plugin, they all need to explicitly remember to call setup().
Neovim provides the same mechanisms as Vim for Lua plugins. The problem (and part of my motivation for writing the nvim-best-practices document) is that not enough plugins use them.
Edit: The Neovim setup antipattern is the Lua equivalent of writing Vimscript functions in autoload and asking users to call them in their configs instead of doing so automatically.
I don't know that I would call it an anti-pattern. It has several advantages over using a global variable:
- it avoids needing to create a global variable in the top level namespace
- if the setup is called lazily, then the user config can also perform other lazy operations at configuration time, including requiring other lua modules
- it allows you to pass a config object or function to your package manager, thus keeping your configuration of a plugin, and the code to require the plugin in the same place.
- it doesn't have the problem that you have to make sure you set the global variable before the plugin is loaded
- it is simpler to handle reconfiguring at runtime. The user just calls setup again. Whereas with a global variable, you don't know if/when the config has changed
- It's not at the top level namespace, it's usually in the `vim.g` or `vim.b` namespace. There's no more namespacing than with a Lua module + function.
- global configuration variables don't have to be tables. They can be a union of `table | fun():table`, which enables laziness. [rustaceanvim does this, for example](https://github.com/mrcjkb/rustaceanvim/blob/12504405821c0587...).
- lazy.nvim's heuristics to auto-detect and invoke `setup` functions and pass "config objects" are a hack that could just as easily have been implemented around global config variables. This is a symptom of the problem, not a solution.
- If you don't need any code to require the plugin, there's also no need to keep the configuration and the code to require it in the same place.
- If a plugin is implemented correctly (by not making lazy loading the responsibility of the user), there's no need to worry about when the user sets the global variable.
- Most plugins' `setup` functions are idempotent. If you want to provide the ability to reconfigure your plugin at runtime, you can provide a `reload(opts)` function that sets the global config variable and then reinitialises the plugin. Or, you could add a metatable to the config variable that triggers a reload if the plugin has already been initialised. There's hardly ever a valid reason to force the coupling of configuration and initialisation on your plugin's users.
The settings variable convention is not good, uses random variable prefixes. A new convention is needed, then the ball can start rolling on that. Until then the lazy nvim and/or setup paradigm is useful.
You don"t have to use a separate variable prefix for each config option. A plugin's config variable can just be a table/dictionary.
We need a uniform convention for this. Hopefully then vim.pack enforces something.
AFAIK using setup() is actually a cargo-cult practice and discouraged by the Neovim maintainers.
echasnovski seems to like it (and he's a maintainer I think)
His use case is mini.nvim, a huge bundle of plugins where you most likely don't want each plugin initialising automatically.
He and I are on very opposite ends of the "setup spectrum", but we have found common ground, which is that you shouldn't cargo cult it: https://github.com/neovim/neovim/pull/35600/files
- [deleted]