From dc841d070ed1b588e3058f81685e4458997e9124 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sun, 10 Jul 2022 11:47:34 -0400 Subject: [PATCH] No longer depend on nvim-lspconfig Revert "Revert "feat: no longer require nvim-lspconfig (#27)" (#30)" This reverts commit 67bb9a1c504fc522391b83f1f46be1a1ef98918a. This reverts the #30, which is a revert of #27. We can merge this when `vim.fs` and `vim.lsp.start` make it into stable. Closes #5 Lose dependency on lspconfig --- .github/workflows/ci.yml | 1 - README.md | 8 +- lua/elixir/language_server/init.lua | 121 +++++++++++++++------------- lua/elixir/utils.lua | 20 ++--- tests/download_spec.lua | 6 +- 5 files changed, 80 insertions(+), 76 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a10e6e68..3f274d19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/README.md b/README.md index adb50855..3802b99b 100644 --- a/README.md +++ b/README.md @@ -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 @@ -30,6 +30,8 @@ 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") @@ -37,7 +39,7 @@ 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", diff --git a/lua/elixir/language_server/init.lua b/lua/elixir/language_server/init.lua index 3cb21b7d..502c870a 100644 --- a/lua/elixir/language_server/init.lua +++ b/lua/elixir/language_server/init.lua @@ -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") @@ -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() @@ -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, @@ -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 @@ -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 }) @@ -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 @@ -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 diff --git a/lua/elixir/utils.lua b/lua/elixir/utils.lua index 5018159b..bfa43954 100644 --- a/lua/elixir/utils.lua +++ b/lua/elixir/utils.lua @@ -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) @@ -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() diff --git a/tests/download_spec.lua b/tests/download_spec.lua index 27b77e49..a6a78b5b 100644 --- a/tests/download_spec.lua +++ b/tests/download_spec.lua @@ -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)