Right, my bad.
Still, being able to do more to aid the creation and maintenance of packages than just install packages doesn't make something "not a package manager".
When I tried using Gleam, I loved that it came with all the basic tooling I needed and that's what I think is so wonderful about Lux. I don't want to spend my time fiddling around with setting up all the individual tools — I just want to write code. For me, Lux makes the broader experience around building Lua projects a lot more enjoyable.
If I can get lux to deal with the package management scenarios around a few turboLua projects, I’m pretty sure I’m going to ship much more Lua code next year.
Nope. We chose TOML as the default for various reasons:
- Simplicity.
There are use cases for a turing complete configuration language.
Lux is not one of them.
- Ergonomics.
The ability to edit it using the CLI (technically, that could be possible with Lua too, but it would be a lot more complex and not a very pleasant UX).
> which, I don't know if that's the right call?
The reason we currently support importing a Lua extra.rockspec is ease of migration for complex projects, e.g. with platform-specific overrides (not yet supported by the TOML spec).
This perplexes me. Lua was conceived as a configuration language and the whole point of a configuration language is you edit a config file. Trying to abstract this away behind a CLI seems like it misses the ethos of Lua.
It’s also a tad strange that a package manager designed for Lua isn’t written in Lua. Presumably Lua developers already have Lua installed, know Lua, and would more likely contribute to a project written in Lua.
> Trying to abstract this away behind a CLI seems like it misses the ethos of Lua.
With `lx add <package>`, you can install the package and add it to und config file in one step. And do things like fail if the package or version doesn't exist or isn't compatible with your system.
You can provide editor plugins or use LSP to give users hints if there's an update available, and use code actions to update them, etc.
> It’s also a tad strange that a package manager designed for Lua isn’t written in Lua.
Again, the fact that Lux relates to Lua is a pretty weak argument for choosing Lua as a language to write or configure it in.
Lots of Lua libraries and packages aren't written in Lua, but are built with Lua bindings.
Lua (which as you yourself just mentioned was conceived as a configuration language) is a pretty poor choice for something with the scope of Lux.
In fact, luarocks was recently rewritten in Teal.
Lux has a Lua API (lux-lua) which means it can be embedded or used as a Lua library.
> Presumably Lua developers already have Lua installed, know Lua, and would more likely contribute to a project written in Lua.
We're not worried about finding contributors. If anything, what we need are high quality contributions. Lua developers who only know Lua are not what we're looking for.
Thanks that does answer my question! Had you considered parsing a subset of lua to get the properties you want? That way users don't have to learn a whole other syntax. I'm thinking in particular of my students whom I teach lua. They struggle enough learning one language, having to teach a second with all its quirks seems like a lot to throw at them.
I wouldn't present it to them as "these config files are the same thing as Lua but without loops", but instead "these are config files and they have the same syntax as the Lua records we just learned about". And I would prefer that over "these are config files and they have a different syntax as the Lua records we just learned about." Although I can see merits on discussing that syntax differences exist between languages, that tends to overwhelm people learning their first language.
That's a neat idea, but it would mean we'd have to maintain our own library.
When editing with the CLI, you have to make sure you preserve comments, which the toml-edit crate does quite well.
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.
- 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.