diff --git a/.editorconfig b/.editorconfig index b328442c..ed0098e4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -69,3 +69,7 @@ insert_final_newline = unset trim_trailing_whitespace = unset indent_style = unset indent_size = unset + +[*/**/config/internal.lua] +indent_size = unset +indent_style = unset diff --git a/README.md b/README.md index c41aa3ed..39248f61 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ - Name-based installation (` "nvim-neorg/neorg" ` becomes `:Rocks install neorg` instead). - Automatic dependency and build script management. +- Supports [multiple versions of the same dependency](https://github.com/luarocks/luarocks/wiki/Using-LuaRocks#multiple-versions-using-the-luarocks-package-loader). - True semver versioning! - Minimal, non-intrusive UI. - Async execution. diff --git a/doc/rocks.txt b/doc/rocks.txt index 8bb1fa12..1f2bbca3 100644 --- a/doc/rocks.txt +++ b/doc/rocks.txt @@ -84,6 +84,7 @@ RocksOpts *RocksOpts* {dynamic_rtp?} (boolean) Whether to automatically add freshly installed plugins to the 'runtimepath'. Defaults to `true` for the best default experience. {generate_help_pages?} (boolean) Whether to re-generate plugins help pages after installation/upgrade. {reinstall_dev_rocks_on_update} (boolean) Whether to reinstall 'dev' rocks on update (Default: `true`, as rocks.nvim cannot determine if 'dev' rocks are up to date). + {enable_luarocks_loader} (boolean) Whether to use the luarocks loader to support multiple dependencies (Default: `true`) ============================================================================== diff --git a/lua/rocks/config/init.lua b/lua/rocks/config/init.lua index b85bfb5f..e63d0b56 100644 --- a/lua/rocks/config/init.lua +++ b/lua/rocks/config/init.lua @@ -21,6 +21,7 @@ local config = {} ---@field dynamic_rtp? boolean Whether to automatically add freshly installed plugins to the 'runtimepath'. Defaults to `true` for the best default experience. ---@field generate_help_pages? boolean Whether to re-generate plugins help pages after installation/upgrade. ---@field reinstall_dev_rocks_on_update boolean Whether to reinstall 'dev' rocks on update (Default: `true`, as rocks.nvim cannot determine if 'dev' rocks are up to date). +---@field enable_luarocks_loader boolean Whether to use the luarocks loader to support multiple dependencies (Default: `true`) ---@type RocksOpts | fun():RocksOpts vim.g.rocks_nvim = vim.g.rocks_nvim diff --git a/lua/rocks/config/internal.lua b/lua/rocks/config/internal.lua index 1d14f861..17742dfe 100644 --- a/lua/rocks/config/internal.lua +++ b/lua/rocks/config/internal.lua @@ -40,6 +40,8 @@ local default_config = { generate_help_pages = true, ---@type boolean Whether to reinstall 'dev' rocks on update reinstall_dev_rocks_on_update = true, + ---@type boolean Whether to use the luarocks loader to support multiple dependencies + enable_luarocks_loader = true, ---@class RocksConfigDebugInfo debug_info = { ---@type boolean @@ -73,6 +75,8 @@ local default_config = { local rocks_toml = config.get_rocks_toml() return vim.tbl_deep_extend("force", rocks_toml.rocks or {}, rocks_toml.plugins or {}) end, + ---@type string + luarocks_config = nil, } ---@type RocksOpts @@ -99,6 +103,24 @@ if #config.debug_info.unrecognized_configs > 0 then ) end +local luarocks_config_path = vim.fs.joinpath(config.rocks_path, "luarocks-config.lua") +fs.write_file( + luarocks_config_path, + "w+", + ([==[ +lua_version = 5.1 +rocks_trees = { + { + name = "rocks.nvim", + root = "%s", + }, +} +]==]):format(config.rocks_path) +) + +---@diagnostic disable-next-line: inject-field +config.luarocks_config = ('"%s"'):format(luarocks_config_path) + return config --- config.lua ends here diff --git a/lua/rocks/luarocks.lua b/lua/rocks/luarocks.lua index 615b31fd..b2dfb992 100644 --- a/lua/rocks/luarocks.lua +++ b/lua/rocks/luarocks.lua @@ -72,7 +72,7 @@ luarocks.cli = function(args, on_exit, opts) lock = nio.control.future() end opts.env = vim.tbl_deep_extend("force", opts.env or {}, { - LUAROCKS_CONFIG = "", + LUAROCKS_CONFIG = config.luarocks_config, TREE_SITTER_LANGUAGE_VERSION = tostring(vim.treesitter.language_version), }) local luarocks_cmd = { diff --git a/plugin/rocks.lua b/plugin/rocks.lua index 2a906dba..8a556e59 100644 --- a/plugin/rocks.lua +++ b/plugin/rocks.lua @@ -6,6 +6,30 @@ local nio = require("nio") local adapter = require("rocks.adapter") local config = require("rocks.config.internal") +local function get_luarocks_loader_path_from_luarocks() + local sc = vim.system({ config.luarocks_binary, "which", "luarocks.loader" }):wait() + return sc.stdout and sc.stdout:match("(%S+)loader.lua") +end + +-- Initialize the luarocks loader +if config.enable_luarocks_loader then + local default_luarocks_binary = vim.fs.joinpath(config.rocks_path, "bin", "luarocks") + local luarocks_loader_path = config.luarocks_binary == default_luarocks_binary + and vim.fs.joinpath(default_luarocks_binary, "share", "lua", "5.1", "luarocks", "?.lua") + or get_luarocks_loader_path_from_luarocks() + if luarocks_loader_path then + package.path = package.path .. ";" .. luarocks_loader_path .. "?.lua" + vim.env.LUAROCKS_CONFIG = config.luarocks_config + local ok, err = pcall(require, "luarocks.loader") + -- TODO: log errors + if not ok then + vim.notify("Failed to initialize luarocks loader: " .. err, vim.log.levels.ERROR, { + title = "rocks.nvim", + }) + end + end +end + -- Set up the Rocks user command require("rocks.commands").create_commands()