Skip to content
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

feat(nextls): multi-root workspaces #184

Merged
merged 2 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions lua/elixir/iter/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,22 @@ end
local packedmt = {}

local function unpack(t)
if type(t) == 'table' and getmetatable(t) == packedmt then
if type(t) == "table" and getmetatable(t) == packedmt then
return _G.unpack(t, 1, t.n)
end
return t
end

local function pack(...)
local n = select('#', ...)
local n = select("#", ...)
if n > 1 then
return setmetatable({ n = n, ... }, packedmt)
end
return ...
end

local function sanitize(t)
if type(t) == 'table' and getmetatable(t) == packedmt then
if type(t) == "table" and getmetatable(t) == packedmt then
-- Remove length tag
t.n = nil
end
Expand Down Expand Up @@ -448,7 +448,7 @@ end
---
---@return Iter
function Iter.rev(self)
error('rev() requires a list-like table')
error("rev() requires a list-like table")
return self
end

Expand Down Expand Up @@ -479,7 +479,7 @@ end
---
---@return any
function Iter.peek(self) -- luacheck: no unused args
error('peek() requires a list-like table')
error("peek() requires a list-like table")
end

---@private
Expand Down Expand Up @@ -513,7 +513,7 @@ end
---
---@return any
function Iter.find(self, f)
if type(f) ~= 'function' then
if type(f) ~= "function" then
local val = f
f = function(v)
return v == val
Expand Down Expand Up @@ -560,12 +560,12 @@ end
---
---@return any
function Iter.rfind(self, f) -- luacheck: no unused args
error('rfind() requires a list-like table')
error("rfind() requires a list-like table")
end

---@private
function ListIter.rfind(self, f) -- luacheck: no unused args
if type(f) ~= 'function' then
if type(f) ~= "function" then
local val = f
f = function(v)
return v == val
Expand Down Expand Up @@ -599,7 +599,7 @@ end
---
---@return any
function Iter.nextback(self) -- luacheck: no unused args
error('nextback() requires a list-like table')
error("nextback() requires a list-like table")
end

function ListIter.nextback(self)
Expand Down Expand Up @@ -628,7 +628,7 @@ end
---
---@return any
function Iter.peekback(self) -- luacheck: no unused args
error('peekback() requires a list-like table')
error("peekback() requires a list-like table")
end

function ListIter.peekback(self)
Expand Down Expand Up @@ -686,7 +686,7 @@ end
---@param n number Number of values to skip.
---@return Iter
function Iter.skipback(self, n) -- luacheck: no unused args
error('skipback() requires a list-like table')
error("skipback() requires a list-like table")
return self
end

Expand Down Expand Up @@ -760,7 +760,7 @@ end
---@param last number
---@return Iter
function Iter.slice(self, first, last) -- luacheck: no unused args
error('slice() requires a list-like table')
error("slice() requires a list-like table")
return self
end

Expand Down Expand Up @@ -909,9 +909,9 @@ end
---@private
function Iter.new(src, ...)
local it = {}
if type(src) == 'table' then
if type(src) == "table" then
local mt = getmetatable(src)
if mt and type(mt.__call) == 'function' then
if mt and type(mt.__call) == "function" then
---@private
function it.next()
return src()
Expand All @@ -937,7 +937,7 @@ function Iter.new(src, ...)
return ListIter.new(t)
end

if type(src) == 'function' then
if type(src) == "function" then
local s, var = ...

--- Use a closure to handle var args returned from iterator
Expand All @@ -957,7 +957,7 @@ function Iter.new(src, ...)

setmetatable(it, Iter)
else
error('src must be a table or function')
error("src must be a table or function")
end
return it
end
Expand Down
58 changes: 38 additions & 20 deletions lua/elixir/nextls/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ function M.setup(opts)
local cmd = event.data.cmd
local auto_update = event.data.auto_update
local options = event.data.opts
local root_dir = event.data.root_dir
local workspace_folders = event.data.workspace_folders

vim.lsp.start({
name = "NextLS",
cmd = cmd,
Expand All @@ -28,9 +29,7 @@ function M.setup(opts)
init_options = options.init_options or vim.empty_dict(),
settings = {},
capabilities = options.capabilities or vim.lsp.protocol.make_client_capabilities(),
workspace_folders = {
{ name = root_dir, uri = vim.uri_from_fname(root_dir) },
},
workspace_folders = workspace_folders,
on_attach = options.on_attach or function() end,
}, {
bufnr = 0,
Expand All @@ -50,35 +49,54 @@ function M.setup(opts)
group = nextls_group,
pattern = { "elixir", "eelixir", "heex", "surface" },
callback = function()
local lock_matches = vim.fs.find({ "mix.lock" }, {
stop = vim.uv.os_homedir(),
upward = true,
path = vim.fs.dirname(vim.api.nvim_buf_get_name(0)),
})
local lock_matches
local mix_exs_matches
local workspace_folders
if vim.g.workspace then
local uri = vim.uri_from_bufnr(0)
if
vim.iter(vim.g.workspace.folders):any(function(folder)
return vim.startswith(uri, folder.uri)
end)
then
workspace_folders = vim.g.workspace.folders
end
else
lock_matches = vim.fs.find({ "mix.lock" }, {
stop = vim.uv.os_homedir(),
upward = true,
path = vim.fs.dirname(vim.api.nvim_buf_get_name(0)),
})

local mix_exs_matches = vim.fs.find({ "mix.exs" }, {
stop = vim.uv.os_homedir(),
upward = true,
path = vim.fs.dirname(vim.api.nvim_buf_get_name(0)),
})
mix_exs_matches = vim.fs.find({ "mix.exs" }, {
stop = vim.uv.os_homedir(),
upward = true,
path = vim.fs.dirname(vim.api.nvim_buf_get_name(0)),
})
local file = lock_matches[1] or mix_exs_matches[1]

local file = lock_matches[1] or mix_exs_matches[1]
if file then
local root_dir = vim.fs.dirname(file)
assert(type(root_dir) == "string", "expected root_dir to be a string")
workspace_folders = {
{ name = vim.fs.basename(root_dir), uri = vim.uri_from_fname(root_dir) },
}
end
end

if file then
if workspace_folders then
local cmd
if type(opts.port) == "number" then
cmd = vim.lsp.rpc.connect("127.0.0.1", opts.port)
else
cmd = { opts.cmd, "--stdio" }
end

local root_dir = vim.fs.dirname(file)
assert(type(root_dir) == "string", "expected root_dir to be a string")
local activate = function()
vim.api.nvim_exec_autocmds("User", {
pattern = "ElixirToolsNextLSActivate",
data = {
root_dir = root_dir,
workspace_folders = workspace_folders,
cmd = cmd,
auto_update = opts.auto_update,
opts = opts,
Expand All @@ -96,7 +114,7 @@ function M.setup(opts)
utils.download_nextls()
activate()
else
vim.b.elixir_tools_prompted_nextls_install = true
vim.b["elixir_tools_prompted_nextls_install"] = true
end
end)
else
Expand Down
Loading