diff options
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/nvim_lsp.lua | 5 | ||||
| -rw-r--r-- | lua/nvim_lsp/clangd.lua | 5 | ||||
| -rw-r--r-- | lua/nvim_lsp/elmls.lua | 141 | ||||
| -rw-r--r-- | lua/nvim_lsp/skeleton.lua | 6 | ||||
| -rw-r--r-- | lua/nvim_lsp/util.lua | 10 |
5 files changed, 160 insertions, 7 deletions
diff --git a/lua/nvim_lsp.lua b/lua/nvim_lsp.lua index a28bc4d5..4a6518f2 100644 --- a/lua/nvim_lsp.lua +++ b/lua/nvim_lsp.lua @@ -1,8 +1,9 @@ local skeleton = require 'nvim_lsp/skeleton' -require 'nvim_lsp/gopls' -require 'nvim_lsp/texlab' require 'nvim_lsp/clangd' +require 'nvim_lsp/elmls' +require 'nvim_lsp/gopls' require 'nvim_lsp/pyls' +require 'nvim_lsp/texlab' local M = { util = require 'nvim_lsp/util'; diff --git a/lua/nvim_lsp/clangd.lua b/lua/nvim_lsp/clangd.lua index b0d4ec25..8abe8ea2 100644 --- a/lua/nvim_lsp/clangd.lua +++ b/lua/nvim_lsp/clangd.lua @@ -13,11 +13,11 @@ skeleton.clangd = { log_level = lsp.protocol.MessageType.Warning; settings = {}; capabilities = default_capabilities; - on_init = vim.schedule_wrap(function(client, result) + on_init = function(client, result) if result.offsetEncoding then client.offset_encoding = result.offsetEncoding end - end) + end }; -- commands = {}; -- on_new_config = function(new_config) end; @@ -37,4 +37,3 @@ as compile_commands.json or, for simpler projects, a compile_flags.txt. }; } -- vim:et ts=2 sw=2 - diff --git a/lua/nvim_lsp/elmls.lua b/lua/nvim_lsp/elmls.lua new file mode 100644 index 00000000..08a28c45 --- /dev/null +++ b/lua/nvim_lsp/elmls.lua @@ -0,0 +1,141 @@ +local skeleton = require 'nvim_lsp/skeleton' +local util = require 'nvim_lsp/util' +local lsp = vim.lsp +local fn = vim.fn +local api = vim.api +local need_bins = util.need_bins + +local default_capabilities = lsp.protocol.make_client_capabilities() +default_capabilities.offsetEncoding = {"utf-8", "utf-16"} + +local bin_name = "elm-language-server" + +local install_dir = util.path.join(fn.stdpath("cache"), "nvim_lsp", "elmls") +local function get_install_info() + local bin_dir = util.path.join(install_dir, "node_modules", ".bin") + local bins = { bin_dir = bin_dir; install_dir = install_dir; } + bins.elmls = util.path.join(bin_dir, bin_name) + bins.elm = util.path.join(bin_dir, "elm") + bins.elm_format = util.path.join(bin_dir, "elm-format") + bins.elm_test = util.path.join(bin_dir, "elm-test") + bins.is_installed = need_bins(bins.elmls, bins.elm, bins.elm_format, bins.elm_test) + return bins +end + +local global_commands = { + ElmlsInstall = { + function() + if get_install_info().is_installed then + return print("ElmLS is already installed") + end + skeleton.elmls.install() + end; + description = 'Install elmls and its dependencies to stdpath("cache")/nvim_lsp/elmls'; + }; + ElmlsInstallInfo = { + function() + local install_info = get_install_info() + if not install_info.is_installed then + return print("ElmLS is not installed") + end + print(vim.inspect(install_info)) + end; + description = 'Print installation info for `elmls`'; + }; +}; + +util.create_module_commands("elmls", global_commands) + +local elm_root_pattern = util.root_pattern("elm.json") + +skeleton.elmls = { + default_config = { + cmd = {bin_name}; + -- TODO(ashkan) if we comment this out, it will allow elmls to operate on elm.json. It seems like it could do that, but no other editor allows it right now. + filetypes = {"elm"}; + root_dir = function(fname, bufnr) + local filetype = api.nvim_buf_get_option(0, 'filetype') + if filetype == 'elm' or (filetype == 'json' and fname:match("elm%.json$")) then + return elm_root_pattern(fname) + end + end; + log_level = lsp.protocol.MessageType.Warning; + settings = {}; + init_options = { + elmPath = "elm", + elmFormatPath = "elm-format", + elmTestPath = "elm-test", + elmAnalyseTrigger = "change", + }; + capabilities = default_capabilities; + on_init = function(client, result) + if result.offsetEncoding then + client.offset_encoding = result.offsetEncoding + end + end + }; + commands = global_commands; + on_new_config = function(new_config) + local install_info = get_install_info() + if install_info.is_installed then + new_config.cmd = {install_info.elmls} + util.tbl_deep_extend(new_config.init_options, { + elmPath = install_info.elm; + elmFormatPath = install_info.elm_format; + elmTestPath = install_info.elm_test; + }) + end + print(vim.inspect(new_config)) + end; + docs = { + description = [[ +https://github.com/elm-tooling/elm-language-server#installation + +You can install elmls automatically to the path at + `stdpath("cache")/nvim_lsp/elmls` +by using the function `nvim_lsp.elmls.install()` or the command `:ElmlsInstall`. + +This will only install if it can't find `elm-language-server` and if it hasn't +been installed before by neovim. + +You can see installation info via `:ElmlsInstallInfo` or via +`nvim_lsp.elmls.get_install_info()`. This will let you know if it is installed. + +If you don't want to use neovim to install it, then you can use: +```sh +npm install -g elm elm-test elm-format @elm-tooling/elm-language-server +``` +]]; + default_config = { + root_dir = [[root_pattern("elm.json")]]; + on_init = [[function to handle changing offsetEncoding]]; + capabilities = [[default capabilities, with offsetEncoding utf-8]]; + }; + }; +} + +function skeleton.elmls.install() + if not need_bins(bin_name) then return end + if not need_bins("sh", "npm", "mkdir", "cd") then + vim.api.nvim_err_writeln('Installation requires "sh", "npm", "mkdir", "cd"') + return + end + local install_info = get_install_info() + if install_info.is_installed then + return + end + local cmd = io.popen("sh", "w") + local install_script = ([[ +set -eo pipefail +mkdir -p "{{install_dir}}" +cd "{{install_dir}}" +npm install elm elm-test elm-format @elm-tooling/elm-language-server +]]):gsub("{{(%S+)}}", install_info) + print(install_script) + cmd:write(install_script) + cmd:close() +end + +skeleton.elmls.get_install_info = get_install_info +-- vim:et ts=2 sw=2 + diff --git a/lua/nvim_lsp/skeleton.lua b/lua/nvim_lsp/skeleton.lua index 9fa6f835..0d69fed0 100644 --- a/lua/nvim_lsp/skeleton.lua +++ b/lua/nvim_lsp/skeleton.lua @@ -130,9 +130,11 @@ function skeleton.__newindex(t, template_name, template) function manager.try_add() local root_dir = get_root_dir(api.nvim_buf_get_name(0), api.nvim_get_current_buf()) - print(api.nvim_get_current_buf(), root_dir) + if not root_dir then return end local id = manager.add(root_dir) - lsp.buf_attach_client(0, id) + if id then + lsp.buf_attach_client(0, id) + end end M.manager = manager diff --git a/lua/nvim_lsp/util.lua b/lua/nvim_lsp/util.lua index 190869e6..2b13d227 100644 --- a/lua/nvim_lsp/util.lua +++ b/lua/nvim_lsp/util.lua @@ -2,6 +2,7 @@ local validate = vim.validate local api = vim.api local lsp = vim.lsp local uv = vim.loop +local fn = vim.fn local M = {} @@ -89,6 +90,15 @@ function M.create_module_commands(module_name, commands) end end +function M.need_bins(...) + for i = 1, select("#", ...) do + if 0 == fn.executable((select(i, ...))) then + return false + end + end + return true +end + -- Some path utilities M.path = (function() local function exists(filename) |
