folke / lazy.nvim

💤 A modern plugin manager for Neovim
https://lazy.folke.io/
Apache License 2.0
14.14k stars 340 forks source link

feature: Lua Rocks Support #253

Closed alisonjenkins closed 3 months ago

alisonjenkins commented 1 year ago

Did you check the docs?

Is your feature request related to a problem? Please describe.

I recently started making use of the Lua Rocks support that Packer has to be able to load JSON using the lua-cjson 'rock' and would like to be able to continue making use of it if possible.

Describe the solution you'd like

Support for a rocks table that we pass along side a plugin which acts like a dependency. That should then automatically download and install the lua rock so that it can be used by the plugin and it's config function.

Describe alternatives you've considered

No decent alternative solution that I am aware of short of manually installing luarocks and figuring out how to have Neovim load the rocks from a path which is not ideal considering that I have multiple other people using my config and I also use my config on multiple computers.

Additional context

No response

folke commented 1 year ago

Thank you for the suggestion, but I'm not planning luarocks support

folke commented 1 year ago

btw, lua-cjson is builtin Neovim since 0.7.0. It's available as vim.json.encode and decode

folke commented 1 year ago

See also https://github.com/neovim/neovim/pull/14871

tzachar commented 1 year ago

@folke Can you please elaborate why you are against supporting luarocks?

folke commented 1 year ago

@tzachar because I never needed that ever

tzachar commented 1 year ago

Will you be open to accepting PRs to add support for lua rocks?

folke commented 1 year ago

Give me one good use case? And why would there need to be support for that in lazy.nvim directly? You can still use lua-rocks and add the lua-rocks path to the rtp no?

tzachar commented 1 year ago

Give me one good use case?

When you want to use some data structure in a plugin, and dont want to include the code in the plugim itself?

And why would there need to be support for that in lazy.nvim directly? You can still use lua-rocks and add the lua-rocks path to the rtp no?

Its easier to pull dependencies from a single place. And as packer supports luarocks, there are clearly other use cases.

Wdyt?

folke commented 1 year ago

I haven't seen a single plugin that has lua-rocks dependencies. I'm not interested in adding or merging a PR to add lua-rocks functionality. This would only increase complexity and possibly introduce bugs for something that would never be used.

hinell commented 1 year ago

Support for luarocks may be as simple as:

-- Assuming that `package.path` is set from `$ luarocks path` command 
os.execute("luarocks install " .. plugin.name)

Packer provides support for it but it's a bit complicated.

mrcjkb commented 1 year ago

I think we've got ourselves a bit of a vicious cycle.

Plugins don't use LuaRocks because Neovim and plugin managers don't support it (packer uses hererocks for LuaRocks support, which based on my tests can't fetch dependencies). And the LuaRocks bundle is too large to bundle with Neovim (although the bits needed to install packages may be smaller).

Plugin managers don't support LuaRocks properly because there aren't enough plugins that use it.

The status quo:

I'm aware of an attempt at creating a neovim package specification, which may help alleviate some of these problems. But why reinvent the wheel?

Nix will install the LuaRocks package (including its dependencies) if a neovim plugin is available on LuaRocks. It'll also install dependencies if it finds a rockspec in the source repo. That seems to work quite well.

I would be happy to see LuaRocks become the standard way of installing Neovim plugins. That being said, I do understand the concerns about maintainability and complexity; much of which has been discussed in https://github.com/wbthomason/packer.nvim/issues/526. Perhaps instead of adding builtin LuaRocks support to Lazy.nvim, an external LuaRocks wrapper could provide specs where dir is set to the LuaRocks package (I might look into that).

In the meantime, I will be doing my part in attempting to get plugins on LuaRocks with the luarocks-tag-release action.

hinell commented 1 year ago

@mrcjkb Adding a builtin luarocks is a bit overkill regarldess of the way it's going to be used lol. I've system wide installation of the former and I don't even think about fetching tonnes of the hererocks and the rest nonse. For the rest, the $ luarocks config --user-config can be used to configure necessariy paths. That's it.

mrcjkb commented 1 year ago

@mrcjkb Adding a builtin luarocks is a bit overkill regarldess of the way it's going to be used lol. I've system wide installation of the former and I don't even think about fetching tonnes of the hererocks and the rest nonse. For the rest, the $ luarocks config --user-config can be used to configure necessariy paths. That's it.

Agreed that a built-in LuaRocks or a bundle would probably be overkill. If LuaRocks provided a lightweight bundle with a lua API just for what's needed to install packages, I wouldn't be so sure. No idea how lightweight such a bundle would be though.

It might not be that simple for plugin managers to just shell out to a system installation. What if someone has LuaRocks configured to use Lua 5.4? Then a system installation would refuse to install any Neovim plugins that expect Lua 5.1/LuaJIT.

tzachar commented 1 year ago

I know that this is not the place to consider these issues, so sorry for venting my frustrations :)

I have to say that @mrcjkb summed the issue perfectly. From my viewpoint, as a plugin writer, every time I need to implement a new feature I have to consider the benefits of using any data structure against the implications of having to (a) find a stand alone implementation or implement it myself and (b) perpetually maintaining said implementation.

The end result is that all of nvim's plugins end up underperforming and are less maintainable. We all lose as a result.

hinell commented 1 year ago

Then a system installation would refuse to install any Neovim plugins that expect Lua 5.1/LuaJIT.

This should be solved at plugin level. Neovim is run by using Luajit which is 100% compatible with Lua 5.1 (see this page for more info)

mrcjkb commented 1 year ago

Support for luarocks may be as simple as:

-- Assuming that `package.path` is set from `$ luarocks path` command 
os.execute("luarocks install " .. plugin.name)

This will not run luarocks with Neovim's LuaJIT bundle as the interpreter.

tomodachi94 commented 1 year ago

What's wrong with adding https://github.com/example/luarocks-rock.lua as a package dependency in the normal fashion?

You could also specify an arbitrary URL but I'm not sure how well that would work.

jghauser commented 1 year ago

This issue has come up in my papis.nvim. The difficulty is that some lua rocks (including the lyaml rock I'm depending on), include c files that need to be compiled. Copying the relevant .lua files isn't enough. And a normal system installation with luarocks doesn't work because then neovim can't find the files. It's possible to get things to work manually, but as you can see in the linked issue, it's not trivial. I'm currently thinking of dropping the lyaml rock and moving to a 'normal' dependency to do what I need (parsing yaml files).

I'm adding this here to show there are definitely some use cases that aren't easily accommodated without lua rocks support and to see if there's maybe something I haven't considered that would make installing my plugin with lazy.nvim easier than I would have thought.

mrcjkb commented 1 year ago

@jghauser something you could try as a workaround is to find out how to build lyaml locally (you can find that info in the rockspec). Then you could tell users to add lyaml to lazy as if it were a normal plugin and put the build command(s) in the build attribute of the plugin spec (equivalent to packer's run attribute).

It's an ugly hack but it might work for some rocks.

jghauser commented 1 year ago

Thanks @mrcjkb! I will give this a try :heart:

derekthecool commented 1 year ago

I remember packer had this feature but never used it. Recently I wanted to use a luarock for the luafun functional programming library.

Thanks to lazy.nvim's awesomeness and the power of git and GitHub I easily created a new repo where I added the lua fun library into a lua directory as a git submodule. https://github.com/derekthecool/luafun_neovim

Then I add it as a plugin in the normal way with lazy.nvim Then boom, problem solved, luarock made plugin.

hinell commented 1 year ago

@derekthecool I went even further: I just copy-pasted some of the code into my snippets/config files. Done.

alexmozaidze commented 10 months ago

Speaking of luafun, plenary has a module that mimics luafun. I know that the plugin is kinda alpha, but it's used successfully in other plugins nonetheless.

Also, NeoVim 0.10 will have iterators builtin! See neovim/neovim #23029

camspiers commented 10 months ago

For installing luarocks when using lazy.nvim you can use the following plugin:

https://github.com/camspiers/luarocks

Example plugin spec for lazy.nvim:

{
  "camspiers/luarocks",
  dependencies = {
    "rcarriga/nvim-notify", -- Optional dependency
  },
  opts = {
    rocks = { "fzy" } -- Specify LuaRocks packages to install
  }
}

You just need to customize rocks = { "fzy" } to add your own rocks. Please note that not all rocks will work due to system incompatibilities, or version incompatibilities.

When a particular luarock is needed by another plugin, make sure the specify camspiers/luarocks as a dependency of that plugin.

As an example, the plugin camspiers/snap can optionally use the fzy luarock, so you might set it up as follows:

require("lazy").setup({
  {
    "camspiers/luarocks",
    dependencies = { "rcarriga/nvim-notify" },
    opts = { rocks = { "fzy" } },
  },
  {
    "camspiers/snap",
    dependencies = { "camspiers/luarocks" },
  }
})
mrcjkb commented 10 months ago

@camspiers nice! But you might want to consider renaming (or joining forces). There's already a rocks.nvim plugin.

camspiers commented 10 months ago

@mrcjkb hmm, interesting, cool project! I'll rename. Thanks for the heads up. Now to think of a name.

mrcjkb commented 10 months ago

@camspiers are you on matrix? It might be interesting to join forces/exchange info.

camspiers commented 10 months ago

@mrcjkb Renamed. Thanks for the heads up. I've sent you a message on matrix. Feel free to reach out there on collaborating.

nickpoorman commented 3 months ago

btw, lua-cjson is builtin Neovim since 0.7.0. It's available as vim.json.encode and decode

@folke Sorry, to res this, but I also have a need for lyaml (which seems to be the main use case here) or any yaml parser. I wonder if maybe we should also have a vim.yaml.encode / vim.yaml.decode to match the json one? My current strategy is to include a tiny lua yaml parser in my config, but it feels like a hack.

I'll give you my use case if it helps. Upon starting up nvim, I want to check if thecwd is a ruby project with a .rubocop.yml file in it and if so load the file to get the configured Layout/LineLength Max value, and set my textwidth and colorcolumn to the value. It's not something I want to hard-code in my settings because different project use different values and I'm constantly having to change it.

jghauser commented 3 months ago

btw, lua-cjson is builtin Neovim since 0.7.0. It's available as vim.json.encode and decode

@folke Sorry, to res this, but I also have a need for lyaml (which seems to be the main use case here) or any yaml parser. I wonder if maybe we should also have a vim.yaml.encode / vim.yaml.decode to match the json one? My current strategy is to include a tiny lua yaml parser in my config, but it feels like a hack.

I'll give you my use case if it helps. Upon starting up nvim, I want to check if thecwd is a ruby project with a .rubocop.yml file in it and if so load the file to get the configured Layout/LineLength Max value, and set my textwidth and colorcolumn to the value. It's not something I want to hard-code in my settings because different project use different values and I'm constantly having to change it.

More of a workaround than a solution, but what I currently do in papis.nvim is to convert the .yaml to .json with yq and then import it with vim.json.decode.

max397574 commented 3 months ago

Not every luarock can just be upstreamed to neovim the best option would of course be if lazy.nvim added luarocks support but apparently folke doesn't want this For now it's possible to use luarocks.nvim like neorg does it

folke commented 3 months ago

Luarocks support is coming.

See https://github.com/folke/lazy.nvim/pull/1528