From 5fe27b3ed00706a5be6a2b8ba6dfc187cb534e39 Mon Sep 17 00:00:00 2001 From: William Boman Date: Sun, 4 Apr 2021 02:18:34 +0200 Subject: init --- lua/nvim-lsp-installer.lua | 12 ++ lua/nvim-lsp-installer/capabilities.lua | 14 +++ lua/nvim-lsp-installer/installer.lua | 133 +++++++++++++++++++++ lua/nvim-lsp-installer/installers/bash-ls.lua | 14 +++ lua/nvim-lsp-installer/installers/css-ls.lua | 14 +++ lua/nvim-lsp-installer/installers/docker-ls.lua | 14 +++ lua/nvim-lsp-installer/installers/eslint-ls.lua | 78 ++++++++++++ lua/nvim-lsp-installer/installers/graphql-ls.lua | 18 +++ lua/nvim-lsp-installer/installers/html-ls.lua | 14 +++ lua/nvim-lsp-installer/installers/json-ls.lua | 14 +++ lua/nvim-lsp-installer/installers/lua-ls.lua | 59 +++++++++ lua/nvim-lsp-installer/installers/python-ls.lua | 15 +++ lua/nvim-lsp-installer/installers/ruby-ls.lua | 36 ++++++ .../installers/typescript-ls.lua | 36 ++++++ lua/nvim-lsp-installer/installers/vim-ls.lua | 14 +++ lua/nvim-lsp-installer/installers/yaml-ls.lua | 14 +++ 16 files changed, 499 insertions(+) create mode 100644 lua/nvim-lsp-installer.lua create mode 100644 lua/nvim-lsp-installer/capabilities.lua create mode 100644 lua/nvim-lsp-installer/installer.lua create mode 100644 lua/nvim-lsp-installer/installers/bash-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/css-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/docker-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/eslint-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/graphql-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/html-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/json-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/lua-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/python-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/ruby-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/typescript-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/vim-ls.lua create mode 100644 lua/nvim-lsp-installer/installers/yaml-ls.lua (limited to 'lua') diff --git a/lua/nvim-lsp-installer.lua b/lua/nvim-lsp-installer.lua new file mode 100644 index 00000000..9febc675 --- /dev/null +++ b/lua/nvim-lsp-installer.lua @@ -0,0 +1,12 @@ +local installer = require('nvim-lsp-installer.installer') + +local M = {} + +M.get_server_installer = installer.get_server_installer +M.get_available_servers = installer.get_available_servers +M.get_installed_servers = installer.get_installed_servers +M.get_uninstalled_servers = installer.get_uninstalled_servers +M.install = installer.install +M.uninstall = installer.uninstall + +return M diff --git a/lua/nvim-lsp-installer/capabilities.lua b/lua/nvim-lsp-installer/capabilities.lua new file mode 100644 index 00000000..a9545aa0 --- /dev/null +++ b/lua/nvim-lsp-installer/capabilities.lua @@ -0,0 +1,14 @@ +local M = {} + +local default_opts = { + with_snippet_support = true, +} + +function M.create(opts) + opts = opts or default_opts + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities.textDocument.completion.completionItem.snippetSupport = opts.with_snippet_support + return capabilities +end + +return M diff --git a/lua/nvim-lsp-installer/installer.lua b/lua/nvim-lsp-installer/installer.lua new file mode 100644 index 00000000..765b0985 --- /dev/null +++ b/lua/nvim-lsp-installer/installer.lua @@ -0,0 +1,133 @@ +local M = {} + +local _INSTALLERS = { + 'vim-ls', + 'graphql-ls', + 'lua-ls', + 'typescript-ls', + 'css-ls', + 'html-ls', + 'json-ls', + 'yaml-ls', + 'bash-ls', + 'docker-ls', + 'ruby-ls', + 'eslint-ls', +} + +local function escape_quotes(str) + return string.format("%q", str) +end + +function M.get_server_installer(server) + return require('nvim-lsp-installer.installers.' .. server) +end + +function M.get_available_servers() return _INSTALLERS end + +function M.get_installed_servers() + local installed_servers = {} + for _, server in ipairs(M.get_available_servers()) do + local module = M.get_server_installer(server) + if os.execute('test -d ' .. escape_quotes(module.root_dir)) == 0 then + table.insert(installed_servers, server) + end + end + return installed_servers +end + +function M.get_uninstalled_servers() + local installed_servers = M.get_installed_servers() + return vim.tbl_filter( + function (server) + return not vim.tbl_contains(installed_servers, server) + end, + M.get_available_servers() + ) +end + +local function _uninstall(server) + local installer = M.get_server_installer(server) + + -- giggity + if os.execute('rm -rf ' .. escape_quotes(installer.root_dir)) ~= 0 then + error('Could not remove LSP server directory ' .. installer.root_dir) + end +end + +local function _install(server) + local installer = M.get_server_installer(server) + + if installer.pre_install then + installer.pre_install() + end + + -- We run uninstall after pre_install because we don't want to + -- unnecessarily uninstall a server should it no longer pass the + -- pre_install check. + _uninstall(server) + + if os.execute('mkdir -p ' .. escape_quotes(installer.root_dir)) ~= 0 then + error('Could not create LSP server directory ' .. installer.root_dir) + end + + local shell = vim.o.shell + vim.o.shell = '/bin/bash' + vim.cmd [[new]] + vim.fn.termopen( + 'set -e;\n' .. installer.install_cmd, + { + cwd = installer.root_dir, + on_exit = function (_, exit_code) + if exit_code ~= 0 then + vim.api.nvim_err_writeln("Installer failed for " .. server .. ". Exit code: " .. exit_code) + _uninstall(server) + else + print("Successfully installed " .. server) + end + + end + } + ) + vim.o.shell = shell + vim.cmd([[startinsert]]) -- so that the buffer tails the term log nicely +end + +function M.install(server) + local success, error = pcall(_install, server) + if not success then + pcall(_uninstall, server) + vim.api.nvim_err_writeln("Failed to install " .. server .. ". Error=" .. vim.inspect(error)) + end + return success +end + +function M.uninstall(server) + local success, error = pcall(_uninstall, server) + if not success then + vim.api.nvim_err_writeln('Unable to uninstall ' .. server .. '. Error=' .. vim.inspect(error)) + return success + end + print("Successfully uninstalled " .. server) + return success +end + +function M.get_server_root_path(server) + return vim.fn.stdpath('data') .. "/lsp_servers/" .. server +end + +function M.create_lsp_config_installer(module) + return { + install_cmd = module.install_cmd, + root_dir = module.root_dir, + pre_install = module.pre_install, + setup = function(opts) + require'lspconfig'[module.name].setup( + vim.tbl_deep_extend('force', module.default_options, opts) + ) + end, + extras = module.extras or {}, + } +end + +return M diff --git a/lua/nvim-lsp-installer/installers/bash-ls.lua b/lua/nvim-lsp-installer/installers/bash-ls.lua new file mode 100644 index 00000000..d784ca51 --- /dev/null +++ b/lua/nvim-lsp-installer/installers/bash-ls.lua @@ -0,0 +1,14 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('bash') + +return installer.create_lsp_config_installer { + name = "bashls", + root_dir = root_dir, + install_cmd = [[npm install bash-language-server@latest]], + default_options = { + cmd = { root_dir .. "/node_modules/.bin/bash-language-server", "start" }, + capabilities = capabilities.create(), + }, +} diff --git a/lua/nvim-lsp-installer/installers/css-ls.lua b/lua/nvim-lsp-installer/installers/css-ls.lua new file mode 100644 index 00000000..de9a5462 --- /dev/null +++ b/lua/nvim-lsp-installer/installers/css-ls.lua @@ -0,0 +1,14 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('css') + +return installer.create_lsp_config_installer { + name = 'cssls', + root_dir = root_dir, + install_cmd = [[npm install vscode-css-languageserver-bin]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/css-languageserver', '--stdio' }, + capabilities = capabilities.create(), + }, +} diff --git a/lua/nvim-lsp-installer/installers/docker-ls.lua b/lua/nvim-lsp-installer/installers/docker-ls.lua new file mode 100644 index 00000000..4b6d660f --- /dev/null +++ b/lua/nvim-lsp-installer/installers/docker-ls.lua @@ -0,0 +1,14 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('dockerfile') + +return installer.create_lsp_config_installer { + name = 'dockerls', + root_dir = root_dir, + install_cmd = [[npm install dockerfile-language-server-nodejs@latest]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/docker-langserver', '--stdio' }, + capabilities = capabilities.create(), + }, +} diff --git a/lua/nvim-lsp-installer/installers/eslint-ls.lua b/lua/nvim-lsp-installer/installers/eslint-ls.lua new file mode 100644 index 00000000..1682209b --- /dev/null +++ b/lua/nvim-lsp-installer/installers/eslint-ls.lua @@ -0,0 +1,78 @@ +local lspconfig = require'lspconfig' +local configs = require'lspconfig/configs' + +local installer = require'nvim-lsp-installer.installer' + +if not lspconfig.eslintls then + configs.eslintls = { + default_config = { + filetypes = {'javascript', 'javascriptreact', 'typescript', 'typescriptreact'}, + root_dir = lspconfig.util.root_pattern(".eslintrc*", "package.json", ".git"), + settings = { + nodePath = '', -- If this is a non-null/undefined value the eslint LSP runs into runtime exceptions. + validate = 'on', + run = 'onType', + workingDirectory = {mode = "auto"}, + workspaceFolder = { + uri = "/", + name = "root", + }, + codeAction = { + disableRuleComment = { + enable = true, + location = "sameLine", + }, + showDocumentation = { + enable = true + } + }, + }, + }, + } +end + +local ConfirmExecutionResult = { + deny = 1, + confirmationPending = 2, + confirmationCanceled = 3, + approved = 4 +} + +local root_dir = installer.get_server_root_path('eslint') +local install_cmd = [[ +git clone https://github.com/microsoft/vscode-eslint .; +npm install; +cd server; +npm install; +npx tsc; +]] + +return installer.create_lsp_config_installer { + name = "eslintls", + root_dir = root_dir, + install_cmd = install_cmd, + default_options = { + cmd = {'node', root_dir .. '/server/out/eslintServer.js', '--stdio'}, + handlers = { + ["eslint/openDoc"] = function (_, _, open_doc) + os.execute("open " .. open_doc.url) + return {id = nil, result = true} + end, + ["eslint/confirmESLintExecution"] = function () + return ConfirmExecutionResult.approved + end, + ["eslint/probeFailed"] = function () + vim.api.nvim_err_writeln('ESLint probe failed.') + return {id = nil, result = true} + end, + ["eslint/noLibrary"] = function () + vim.api.nvim_err_writeln('Unable to find ESLint library.') + return {id = nil, result = true} + end, + ["eslint/noConfig"] = function () + vim.api.nvim_err_writeln('Unable to find ESLint configuration.') + return {id = nil, result = true} + end, + }, + }, +} diff --git a/lua/nvim-lsp-installer/installers/graphql-ls.lua b/lua/nvim-lsp-installer/installers/graphql-ls.lua new file mode 100644 index 00000000..b7d5968c --- /dev/null +++ b/lua/nvim-lsp-installer/installers/graphql-ls.lua @@ -0,0 +1,18 @@ +local util = require('lspconfig.util') + +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('graphql') + +return installer.create_lsp_config_installer { + name = "graphql", + root_dir = root_dir, + install_cmd = [[npm install graphql-language-service-cli@latest graphql]], + default_options = { + cmd = { root_dir .. "/node_modules/.bin/graphql-lsp", "server", "-m", "stream" }, + filetypes = { 'typescriptreact', 'javascriptreact', 'graphql' }, + root_dir = util.root_pattern('.git', '.graphqlrc'), + capabilities = capabilities.create(), + }, +} diff --git a/lua/nvim-lsp-installer/installers/html-ls.lua b/lua/nvim-lsp-installer/installers/html-ls.lua new file mode 100644 index 00000000..ddcf4771 --- /dev/null +++ b/lua/nvim-lsp-installer/installers/html-ls.lua @@ -0,0 +1,14 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('html') + +return installer.create_lsp_config_installer { + name = "html", + root_dir = root_dir, + install_cmd = [[npm install vscode-html-languageserver-bin]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/html-languageserver', '--stdio' }, + capabilities = capabilities.create(), + }, +} diff --git a/lua/nvim-lsp-installer/installers/json-ls.lua b/lua/nvim-lsp-installer/installers/json-ls.lua new file mode 100644 index 00000000..35bf792f --- /dev/null +++ b/lua/nvim-lsp-installer/installers/json-ls.lua @@ -0,0 +1,14 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('json') + +return installer.create_lsp_config_installer { + name = "jsonls", + root_dir = root_dir, + install_cmd = [[npm install vscode-json-languageserver-bin]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/json-languageserver', '--stdio' }, + capabilities = capabilities.create(), + }, +} diff --git a/lua/nvim-lsp-installer/installers/lua-ls.lua b/lua/nvim-lsp-installer/installers/lua-ls.lua new file mode 100644 index 00000000..0c2bd08f --- /dev/null +++ b/lua/nvim-lsp-installer/installers/lua-ls.lua @@ -0,0 +1,59 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('lua') + +local install_cmd = [=[ +rm -rf lua-language-server; +git clone https://github.com/sumneko/lua-language-server; +cd lua-language-server/; +git submodule update --init --recursive; +cd 3rd/luamake; +if [[ $(uname) == Darwin ]]; then + ninja -f ninja/macos.ninja; +elif [[ $(uname) == Linux ]]; then + ninja -f ninja/linux.ninja; +else + >&2 echo "$(uname) not supported."; + exit 1; +fi +cd ../../; +./3rd/luamake/luamake rebuild; +]=] + +local uname_alias = { + Darwin = 'macOS', +} +local uname = vim.fn.system('uname'):gsub("%s+", "") +local bin_dir = uname_alias[uname] or uname + +return installer.create_lsp_config_installer { + name = "sumneko_lua", + root_dir = root_dir, + install_cmd = install_cmd, + pre_install = function() + if vim.fn.executable('ninja') ~= 1 then + error("ninja not installed (see https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages)") + end + end, + default_options = { + cmd = { root_dir .. "/lua-language-server/bin/" .. bin_dir .. "/lua-language-server" , "-E", root_dir .. "/lua-language-server/main.lua"}, + capabilities = capabilities.create(), + settings = { + Lua = { + diagnostics = { + -- Get the language server to recognize the `vim` global + globals = {'vim'} + }, + workspace = { + -- Make the server aware of Neovim runtime files + library = { + [vim.fn.expand('$VIMRUNTIME/lua')] = true, + [vim.fn.expand('$VIMRUNTIME/lua/vim/lsp')] = true, + }, + maxPreload = 10000 + } + } + }, + } +} diff --git a/lua/nvim-lsp-installer/installers/python-ls.lua b/lua/nvim-lsp-installer/installers/python-ls.lua new file mode 100644 index 00000000..3de489d0 --- /dev/null +++ b/lua/nvim-lsp-installer/installers/python-ls.lua @@ -0,0 +1,15 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('python') + +return installer.create_lsp_config_installer { + name = "pyright", + root_dir = root_dir, + install_cmd = [[npm install pyright]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/pyright-langserver', '--stdio' }, + capabilities = capabilities.create(), + on_attach = installer.common_on_attach, + }, +} diff --git a/lua/nvim-lsp-installer/installers/ruby-ls.lua b/lua/nvim-lsp-installer/installers/ruby-ls.lua new file mode 100644 index 00000000..634ae90e --- /dev/null +++ b/lua/nvim-lsp-installer/installers/ruby-ls.lua @@ -0,0 +1,36 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('ruby') + +local install_cmd = [[ +wget -O solargraph.tar $(curl -s https://api.github.com/repos/castwide/solargraph/tags | grep 'tarball_url' | cut -d\" -f4 | head -n1); +rm -rf solargraph; +mkdir solargraph; +tar -xzf solargraph.tar -C solargraph --strip-components 1; +rm solargraph.tar; +cd solargraph; + +bundle install --without development --path vendor/bundle; + +echo '#!/usr/bin/env bash' > solargraph; +echo 'cd "$(dirname "$0")" || exit' >> solargraph; +echo 'bundle exec solargraph $*' >> solargraph; + +chmod +x solargraph; +]] + +return installer.create_lsp_config_installer { + name = "pyright", + root_dir = root_dir, + install_cmd = install_cmd, + pre_install = function () + if vim.fn.executable('bundle') ~= 1 then + error("bundle not installed") + end + end, + default_options = { + cmd = { root_dir .. '/solargraph/solargraph', 'stdio' }, + capabilities = capabilities.create(), + } +} diff --git a/lua/nvim-lsp-installer/installers/typescript-ls.lua b/lua/nvim-lsp-installer/installers/typescript-ls.lua new file mode 100644 index 00000000..c8b2c03e --- /dev/null +++ b/lua/nvim-lsp-installer/installers/typescript-ls.lua @@ -0,0 +1,36 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('tsserver') + +return installer.create_lsp_config_installer { + name = "tsserver", + root_dir = root_dir, + install_cmd = [[npm install typescript-language-server]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/typescript-language-server', '--stdio' }, + capabilities = capabilities.create(), + }, + extras = { + rename_file = function(old, new) + local old_uri = vim.uri_from_fname(old) + local new_uri = vim.uri_from_fname(new) + + -- maybe filter by client name, only send to tsserver? + for _, client in ipairs(vim.lsp.get_active_clients()) do + client.request( + 'workspace/executeCommand', + { + command = '_typescript.applyRenameFile', + arguments = { + { + sourceUri = old_uri, + targetUri = new_uri, + }, + }, + } + ) + end + end + } +} diff --git a/lua/nvim-lsp-installer/installers/vim-ls.lua b/lua/nvim-lsp-installer/installers/vim-ls.lua new file mode 100644 index 00000000..f13a5308 --- /dev/null +++ b/lua/nvim-lsp-installer/installers/vim-ls.lua @@ -0,0 +1,14 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('vim') + +return installer.create_lsp_config_installer { + name = "vimls", + root_dir = root_dir, + install_cmd = [[npm install vim-language-server@latest]], + default_options = { + cmd = { root_dir .. "/node_modules/.bin/vim-language-server", "--stdio" }, + capabilities = capabilities.create(), + } +} diff --git a/lua/nvim-lsp-installer/installers/yaml-ls.lua b/lua/nvim-lsp-installer/installers/yaml-ls.lua new file mode 100644 index 00000000..89d0a976 --- /dev/null +++ b/lua/nvim-lsp-installer/installers/yaml-ls.lua @@ -0,0 +1,14 @@ +local installer = require('nvim-lsp-installer.installer') +local capabilities = require('nvim-lsp-installer.capabilities') + +local root_dir = installer.get_server_root_path('yaml') + +return installer.create_lsp_config_installer { + name = "yamlls", + root_dir = root_dir, + install_cmd = [[npm install yaml-language-server]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/yaml-language-server', '--stdio' }, + capabilities = capabilities.create(), + } +} -- cgit v1.2.3-70-g09d2