Skip to content

No longer depend on nvim-lspconfig #31

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

Merged
merged 1 commit into from
Nov 8, 2022
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
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ jobs:
}
mkdir -p ~/.local/share/nvim/site/pack/vendor/start
git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim
git clone --depth 1 https://github.com/neovim/nvim-lspconfig ~/.local/share/nvim/site/pack/vendor/start/nvim-lspconfig
ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start

- name: Run tests
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

## Install

Requires 0.7+.
Requires 0.8.

```lua
use({ "mhanberg/elixir.nvim", requires = { "neovim/nvim-lspconfig", "nvim-lua/plenary.nvim" }})
use({ "mhanberg/elixir.nvim", requires = { "nvim-lua/plenary.nvim" }})
```

## Getting Started
Expand All @@ -30,14 +30,16 @@ require("elixir").setup()

While the plugin works with a minimal setup, it is much more useful if you add some personal configuration.

Note: Not specifying the `repo`, `branch`, or `tag` options will default to the latest release.

```lua
local elixir = require("elixir")

elixir.setup({
-- specify a repository and branch
repo = "mhanberg/elixir-ls", -- defaults to elixir-lsp/elixir-ls
branch = "mh/all-workspace-symbols", -- defaults to nil, just checkouts out the default branch, mutually exclusive with the `tag` option
tag = "v0.9.0", -- defaults to nil, mutually exclusive with the `branch` option
tag = "v0.11.0", -- defaults to nil, mutually exclusive with the `branch` option

-- alternatively, point to an existing elixir-ls installation (optional)
cmd = "/usr/local/bin/elixir-ls.sh",
Expand Down
121 changes: 64 additions & 57 deletions lua/elixir/language_server/init.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
local lspconfig = require("lspconfig")
local lsputil = require("lspconfig.util")

local Job = require("plenary.job")
local Path = require("plenary.path")
local popup = require("plenary.popup")

Expand All @@ -10,10 +6,13 @@ local Download = require("elixir.language_server.download")
local Compile = require("elixir.language_server.compile")
local Utils = require("elixir.utils")

local default_config = require("lspconfig.server_configurations.elixirls").default_config
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true

local default_install_tag = "tags/v0.11.0"

local elixir_nvim_output_bufnr

local M = {}

local get_cursor_position = function()
Expand All @@ -29,12 +28,10 @@ function M.open_floating_window(buf)
local lines = vim.o.lines
local width = math.ceil(columns * 0.8)
local height = math.ceil(lines * 0.8 - 4)
-- local left = math.ceil((columns - width) * 0.5)
-- local top = math.ceil((lines - height) * 0.5 - 1)

local bufnr = buf or vim.api.nvim_create_buf(false, true)

local win_id = popup.create(bufnr, {
popup.create(bufnr, {
line = 0,
col = 0,
minwidth = width,
Expand Down Expand Up @@ -118,9 +115,8 @@ local nil_buf_id = 999999
local term_buf_id = nil_buf_id

local function test(command)
local row, col = get_cursor_position()
local row, _col = get_cursor_position()
local args = command.arguments[1]
local current_buf_id = vim.api.nvim_get_current_buf()

-- delete the current buffer if it's still open
if vim.api.nvim_buf_is_valid(term_buf_id) then
Expand Down Expand Up @@ -219,7 +215,7 @@ local function install_elixir_ls(opts)
local source_path = Download.clone(tostring(download_dir:absolute()), opts)
local bufnr = M.open_floating_window()

local result = Compile.compile(
Compile.compile(
download_dir:joinpath(source_path):absolute(),
opts.install_path:absolute(),
vim.tbl_extend("force", opts, { bufnr = bufnr })
Expand All @@ -237,7 +233,7 @@ local function make_opts(opts)
if opts.repo then -- if we specified a repo in our conifg, then let's default to HEAD
ref = "HEAD"
else -- else, let's checkout the latest stable release
ref = "tags/v0.10.0"
ref = default_install_tag
end
end

Expand All @@ -253,52 +249,63 @@ function M.setup(opts)
vim.api.nvim_buf_set_name(elixir_nvim_output_bufnr, "ElixirLS Output Panel")
end

opts = opts or {}
lspconfig.elixirls.setup(vim.tbl_extend("keep", {
filetypes = { "elixir", "eelixir", "heex", "surface" },

on_init = lsputil.add_hook_after(default_config.on_init, function(client)
client.commands["elixir.lens.test.run"] = test
end),
on_new_config = function(new_config, new_root_dir)
new_opts = make_opts(opts)

if not opts["cmd"] then
local cmd = M.command {
path = tostring(install_dir),
repo = new_opts.repo,
ref = new_opts.ref,
versions = Version.get(),
}

if not cmd:exists() then
vim.ui.select({ "Yes", "No" }, { prompt = "Install ElixirLS" }, function(choice)
if choice == "Yes" then
install_elixir_ls(vim.tbl_extend("force", new_opts, { install_path = cmd:parent() }))
end
end)

return
else
local updated_config = new_config
updated_config.cmd = { tostring(cmd) }

return updated_config
local elixir_group = vim.api.nvim_create_augroup("elixirnvim", { clear = true })

local start_elixir_ls = function(arg)
local fname = Path.new(arg.file):absolute()

local root_dir = opts.root_dir and opts.root_dir(fname) or Utils.root_dir(fname)
local new_opts = make_opts(opts)

local cmd = M.command {
path = tostring(install_dir),
repo = new_opts.repo,
ref = new_opts.ref,
versions = Version.get(),
}

if not cmd:exists() then
vim.ui.select({ "Yes", "No" }, { prompt = "Install ElixirLS" }, function(choice)
if choice == "Yes" then
install_elixir_ls(vim.tbl_extend("force", new_opts, { install_path = cmd:parent() }))
end
end
end,
handlers = {
["window/logMessage"] = function(err, result, ...)
message = vim.split("[" .. vim.lsp.protocol.MessageType[result.type] .. "] " .. result.message, "\n")

vim.api.nvim_buf_set_lines(elixir_nvim_output_bufnr, -1, -1, false, message)
end,
},
settings = opts.settings or settings,
capabilities = opts.capabilities or capabilities,
root_dir = opts.root_dir or Utils.root_dir,
on_attach = lsputil.add_hook_before(opts.on_attach, M.on_attach),
}, opts))
end)

return
elseif root_dir then
vim.lsp.start(vim.tbl_extend("keep", {
name = "ElixirLS",
cmd = { tostring(cmd) },
commands = {
["elixir.lens.test.run"] = test,
},
settings = opts.settings or M.settings {},
capabilities = opts.capabilities or capabilities,
root_dir = root_dir,
handlers = {
["window/logMessage"] = function(_err, result)
local message =
vim.split("[" .. vim.lsp.protocol.MessageType[result.type] .. "] " .. result.message, "\n")

vim.api.nvim_buf_set_lines(elixir_nvim_output_bufnr, -1, -1, false, message)
end,
},
on_attach = function(...)
if opts.on_attach then
opts.on_attach(...)
end

M.on_attach(...)
end,
}, opts))
end
end

vim.api.nvim_create_autocmd({ "FileType" }, {
group = elixir_group,
pattern = { "elixir", "eelixir", "heex", "surface" },
callback = start_elixir_ls,
})
end

return M
20 changes: 8 additions & 12 deletions lua/elixir/utils.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
local lspconfig = require("lspconfig")
local lsputil = require("lspconfig.util")

local uv = vim.loop

local Path = require("plenary.path")
local M = {}

function M.safe_path(path)
Expand All @@ -20,15 +16,15 @@ function M.root_dir(fname)
fname = vim.fn.getcwd()
end

local path = lsputil.path
local child_or_root_path = lsputil.root_pattern { "mix.exs", ".git" }(fname)
local child_or_root_path =
vim.fs.dirname(vim.fs.find({ "mix.exs", ".git" }, { upward = true, path = fname })[1])
local maybe_umbrella_path =
lsputil.root_pattern { "mix.exs" }(uv.fs_realpath(path.join { child_or_root_path, ".." }))
vim.fs.dirname(vim.fs.find({ "mix.exs" }, { upward = true, path = child_or_root_path })[1])

local has_ancestral_mix_exs_path =
vim.startswith(child_or_root_path, path.join { maybe_umbrella_path, "apps" })
if maybe_umbrella_path and not has_ancestral_mix_exs_path then
maybe_umbrella_path = nil
if maybe_umbrella_path then
if not vim.startswith(child_or_root_path, Path:joinpath(maybe_umbrella_path, "apps"):absolute()) then
maybe_umbrella_path = nil
end
end

local path = maybe_umbrella_path or child_or_root_path or vim.loop.os_homedir()
Expand Down
6 changes: 3 additions & 3 deletions tests/download_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ describe("download", function()
it("can checkout a different tag", function()
local download_dir = "tmp/downloads"

local result = Download.clone(download_dir, { repo = "elixir-lsp/elixir-ls", ref = "tags/v0.9.0" })
local result = Download.clone(download_dir, { repo = "elixir-lsp/elixir-ls", ref = "tags/v0.11.0" })

eq("elixir-lsp/elixir-ls/tags_v0.9.0", result)
assert.True(Path:new(download_dir, "elixir-lsp/elixir-ls/tags_v0.9.0", "mix.exs"):exists())
eq("elixir-lsp/elixir-ls/tags_v0.11.0", result)
assert.True(Path:new(download_dir, "elixir-lsp/elixir-ls/tags_v0.11.0", "mix.exs"):exists())
end)
end)