Skip to content

Commit

Permalink
feat(nextls): multi-root workspaces (#184)
Browse files Browse the repository at this point in the history
* feat(nextls): multi-root workspaces

This patch has a dependency on the `mhanberg/workspace-folders.nvim`
plugin.

To try out the behavior, intsall that plugin and create a
`.code-workspace` file that describes your multi-root workspace (or mono
repo as most call it).

If your monorepo is called "money-factory-io", with the folders
"crypto", "ai-chat-app", and "drop-shipping-cms", your `code-workspace`
would be named `money-factory-io.code-workspace` and look like:

```json
{
  "folders": [
    {"path": "crypto"},
    {"path": "ai-chat-app"},
    {"path": "drop-shipping-cms"},
  ]
}
```

* fixup! feat(nextls): multi-root workspaces
  • Loading branch information
mhanberg authored Nov 10, 2023
1 parent f98a90e commit 156cf40
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 36 deletions.
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

0 comments on commit 156cf40

Please sign in to comment.