From dcf117a8a60d887a2c2ff9d5617a9c39c5ee95fb Mon Sep 17 00:00:00 2001 From: William Boman Date: Mon, 5 Apr 2021 14:19:07 +0200 Subject: rename Installer to Server for clarity (#3) --- README.md | 4 - doc/.gitignore | 1 + doc/nvim-lsp-installer.txt | 34 ++--- lua/nvim-lsp-installer.lua | 12 +- lua/nvim-lsp-installer/installer.lua | 158 -------------------- lua/nvim-lsp-installer/installers/bashls.lua | 12 -- lua/nvim-lsp-installer/installers/cssls.lua | 12 -- lua/nvim-lsp-installer/installers/dockerls.lua | 12 -- lua/nvim-lsp-installer/installers/eslintls.lua | 80 ----------- lua/nvim-lsp-installer/installers/graphql.lua | 16 --- lua/nvim-lsp-installer/installers/html.lua | 12 -- lua/nvim-lsp-installer/installers/jsonls.lua | 12 -- lua/nvim-lsp-installer/installers/pyright.lua | 13 -- lua/nvim-lsp-installer/installers/solargraph.lua | 34 ----- lua/nvim-lsp-installer/installers/sumneko_lua.lua | 57 -------- lua/nvim-lsp-installer/installers/tsserver.lua | 12 -- lua/nvim-lsp-installer/installers/vimls.lua | 12 -- lua/nvim-lsp-installer/installers/yamlls.lua | 12 -- lua/nvim-lsp-installer/server.lua | 167 ++++++++++++++++++++++ lua/nvim-lsp-installer/servers/bashls.lua | 12 ++ lua/nvim-lsp-installer/servers/cssls.lua | 12 ++ lua/nvim-lsp-installer/servers/dockerls.lua | 12 ++ lua/nvim-lsp-installer/servers/eslintls.lua | 80 +++++++++++ lua/nvim-lsp-installer/servers/graphql.lua | 16 +++ lua/nvim-lsp-installer/servers/html.lua | 12 ++ lua/nvim-lsp-installer/servers/jsonls.lua | 12 ++ lua/nvim-lsp-installer/servers/pyright.lua | 13 ++ lua/nvim-lsp-installer/servers/solargraph.lua | 34 +++++ lua/nvim-lsp-installer/servers/sumneko_lua.lua | 57 ++++++++ lua/nvim-lsp-installer/servers/tsserver.lua | 12 ++ lua/nvim-lsp-installer/servers/vimls.lua | 12 ++ lua/nvim-lsp-installer/servers/yamlls.lua | 12 ++ plugin/nvim-lsp-installer.vim | 26 ++-- 33 files changed, 501 insertions(+), 493 deletions(-) create mode 100644 doc/.gitignore delete mode 100644 lua/nvim-lsp-installer/installer.lua delete mode 100644 lua/nvim-lsp-installer/installers/bashls.lua delete mode 100644 lua/nvim-lsp-installer/installers/cssls.lua delete mode 100644 lua/nvim-lsp-installer/installers/dockerls.lua delete mode 100644 lua/nvim-lsp-installer/installers/eslintls.lua delete mode 100644 lua/nvim-lsp-installer/installers/graphql.lua delete mode 100644 lua/nvim-lsp-installer/installers/html.lua delete mode 100644 lua/nvim-lsp-installer/installers/jsonls.lua delete mode 100644 lua/nvim-lsp-installer/installers/pyright.lua delete mode 100644 lua/nvim-lsp-installer/installers/solargraph.lua delete mode 100644 lua/nvim-lsp-installer/installers/sumneko_lua.lua delete mode 100644 lua/nvim-lsp-installer/installers/tsserver.lua delete mode 100644 lua/nvim-lsp-installer/installers/vimls.lua delete mode 100644 lua/nvim-lsp-installer/installers/yamlls.lua create mode 100644 lua/nvim-lsp-installer/server.lua create mode 100644 lua/nvim-lsp-installer/servers/bashls.lua create mode 100644 lua/nvim-lsp-installer/servers/cssls.lua create mode 100644 lua/nvim-lsp-installer/servers/dockerls.lua create mode 100644 lua/nvim-lsp-installer/servers/eslintls.lua create mode 100644 lua/nvim-lsp-installer/servers/graphql.lua create mode 100644 lua/nvim-lsp-installer/servers/html.lua create mode 100644 lua/nvim-lsp-installer/servers/jsonls.lua create mode 100644 lua/nvim-lsp-installer/servers/pyright.lua create mode 100644 lua/nvim-lsp-installer/servers/solargraph.lua create mode 100644 lua/nvim-lsp-installer/servers/sumneko_lua.lua create mode 100644 lua/nvim-lsp-installer/servers/tsserver.lua create mode 100644 lua/nvim-lsp-installer/servers/vimls.lua create mode 100644 lua/nvim-lsp-installer/servers/yamlls.lua diff --git a/README.md b/README.md index 7400e2db..41388be8 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,3 @@ require'nvim-lsp-installer.extras.tsserver'.rename_file(old, new) ```lua require'nvim-lsp-installer.extras.tsserver'.organize_imports(bufname) ``` - -## TODO - -- installer... server... module.... pick one!! diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 00000000..6e92f57d --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1 @@ +tags diff --git a/doc/nvim-lsp-installer.txt b/doc/nvim-lsp-installer.txt index d32915b6..5a19198d 100644 --- a/doc/nvim-lsp-installer.txt +++ b/doc/nvim-lsp-installer.txt @@ -49,12 +49,12 @@ Then, somewhere in your initialization script (see `:h init.lua`): > COMMANDS *nvim-lsp-installer-commands* *:LspInstall* -:LspInstall {server} +:LspInstall {server_name} Installs a language server *:LspUninstall* -:LspUninstall {server} +:LspUninstall {server_name} Uninstalls a language server. @@ -80,38 +80,38 @@ Lua module: nvim-lsp-installer *lsp_installer* *lsp_installer.get_available_servers()* get_available_servers() Return: ~ - (string[]) A list containing all available language servers. + |lsp_installer.Server|[] A list containing all available language servers. *lsp_installer.get_installed_servers()* get_installed_servers() Return: ~ - (Installer[]) A list of installers. See |lsp_installer.Installer|. + |lsp_installer.Server|[] A list of servers that are currently installed. *lsp_installer.get_uninstalled_servers()* get_uninstalled_servers() Return: ~ - (string[]) A list of servers that are not installed. + |lsp_installer.Server|[] A list of servers that are not installed. *lsp_installer.install()* -install({server}) - Installs the provided {server}. If {server} is already installed, it +install({server_name}) + Installs the provided {server_name}. If {server_name} is already installed, it is reinstalled. Parameters: ~ - {server} (string) The server to install. + {server_name} (string) The server to install. *lsp_installer.uninstall()* -uninstall({server}) - Uninstalls the provided {server}. +uninstall({server_name}) + Uninstalls the provided {server_name}. Parameters: ~ - {server} (string) The server to uninstall. + {server_name} (string) The server to uninstall. ============================================================================== -Lua module: nvim-lsp-installer.installer *lsp_installer.installer* +Lua module: nvim-lsp-installer.server *lsp_installer.server* - *lsp_installer.Installer* -class: Installer + *lsp_installer.Server* +class: Server This class enables installing, uninstalling, and setting up language servers. @@ -124,12 +124,12 @@ class: Installer {opts}. - is_installed() - Returns {true} is installer is installed, else returns {false}. + Returns {true} is server is installed, else returns {false}. - install() - Installs this instance of an installer. + Installs this instance of an LSP server. - uninstall() - Uninstalls this instance of an installer. + Uninstalls this instance of an LSP server. vim:tw=78:ft=help:norl: diff --git a/lua/nvim-lsp-installer.lua b/lua/nvim-lsp-installer.lua index e19d27d7..ecf70ad0 100644 --- a/lua/nvim-lsp-installer.lua +++ b/lua/nvim-lsp-installer.lua @@ -1,11 +1,11 @@ -local installer = require('nvim-lsp-installer.installer') +local server = require('nvim-lsp-installer.server') local M = {} -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 +M.get_available_servers = server.get_available_servers +M.get_installed_servers = server.get_installed_servers +M.get_uninstalled_servers = server.get_uninstalled_servers +M.install = server.install +M.uninstall = server.uninstall return M diff --git a/lua/nvim-lsp-installer/installer.lua b/lua/nvim-lsp-installer/installer.lua deleted file mode 100644 index a6789d7d..00000000 --- a/lua/nvim-lsp-installer/installer.lua +++ /dev/null @@ -1,158 +0,0 @@ -local M = {} - -local _INSTALLERS = { - 'bashls', - 'cssls', - 'dockerls', - 'eslintls', - 'graphql', - 'html', - 'jsonls', - 'solargraph', - 'sumneko_lua', - 'tsserver', - 'vimls', - 'yamlls', -} - -local function escape_quotes(str) - return string.format("%q", str) -end - -local function get_server_installer(server) - return pcall(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 pairs(M.get_available_servers()) do - local ok, module = get_server_installer(server) - if not ok then - vim.api.nvim_err_writeln("Unable to find installer for " .. server) - goto continue - end - if module:is_installed() then - table.insert(installed_servers, module) - end - ::continue:: - 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 - -function M.install(server) - local ok, installer = get_server_installer(server) - if not ok then - return vim.api.nvim_err_writeln("Unable to find installer for " .. server) - end - local success, error = pcall(installer.install, installer) - if not success then - pcall(installer.uninstall, installer) - return vim.api.nvim_err_writeln("Failed to install " .. server .. ". Error=" .. vim.inspect(error)) - end -end - -function M.uninstall(server) - local ok, installer = get_server_installer(server) - if not ok then - return vim.api.nvim_err_writeln("Unable to find installer for " .. server) - end - local success, error = pcall(installer.uninstall, installer) - if not success then - vim.api.nvim_err_writeln('Unable to uninstall ' .. server .. '. Error=' .. vim.inspect(error)) - return success - end - print("Successfully uninstalled " .. server) -end - -function M.get_server_root_path(server) - return vim.fn.stdpath('data') .. "/lsp_servers/" .. server -end - -M.Installer = {} -M.Installer.__index = M.Installer - ----@class Installer -function M.Installer:new(opts) - return setmetatable({ - name = opts.name, - _install_cmd = opts.install_cmd, - _root_dir = opts.root_dir, - _default_options = opts.default_options, - _pre_install = opts.pre_install, - }, M.Installer) -end - -function M.Installer:setup(opts) - -- We require the lspconfig server here in order to do it as late as possible. - -- The reason for this is because once a lspconfig server has been imported, it's - -- automatically registered with lspconfig and causes it to show up in :LspInfo and whatnot. - require'lspconfig'[self.name].setup( - vim.tbl_deep_extend('force', self._default_options, opts) - ) -end - -function M.Installer:is_installed() - return os.execute('test -d ' .. escape_quotes(self._root_dir)) == 0 -end - -function M.Installer:create_root_dir() - if os.execute('mkdir -p ' .. escape_quotes(self._root_dir)) ~= 0 then - error('Could not create LSP server directory ' .. self._root_dir) - end -end - -function M.Installer:install() - if self._pre_install then - self._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. - self:uninstall() - - self:create_root_dir() - - local shell = vim.o.shell - vim.o.shell = '/bin/bash' - vim.cmd [[new]] - vim.fn.termopen( - 'set -e;\n' .. self._install_cmd, - { - cwd = self._root_dir, - on_exit = function (_, exit_code) - if exit_code ~= 0 then - vim.api.nvim_err_writeln("Installer failed for " .. self.name .. ". Exit code: " .. exit_code) - self:uninstall() - else - print("Successfully installed " .. self.name) - end - - end - } - ) - vim.o.shell = shell - vim.cmd([[startinsert]]) -- so that the buffer tails the term log nicely -end - -function M.Installer:uninstall() - -- giggity - if os.execute('rm -rf ' .. escape_quotes(self._root_dir)) ~= 0 then - error('Could not remove LSP server directory ' .. self._root_dir) - end - -end - -return M diff --git a/lua/nvim-lsp-installer/installers/bashls.lua b/lua/nvim-lsp-installer/installers/bashls.lua deleted file mode 100644 index 68b29c41..00000000 --- a/lua/nvim-lsp-installer/installers/bashls.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('bash') - -return installer.Installer:new { - 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" }, - }, -} diff --git a/lua/nvim-lsp-installer/installers/cssls.lua b/lua/nvim-lsp-installer/installers/cssls.lua deleted file mode 100644 index 23010cd2..00000000 --- a/lua/nvim-lsp-installer/installers/cssls.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('css') - -return installer.Installer:new { - 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' }, - }, -} diff --git a/lua/nvim-lsp-installer/installers/dockerls.lua b/lua/nvim-lsp-installer/installers/dockerls.lua deleted file mode 100644 index 021b098b..00000000 --- a/lua/nvim-lsp-installer/installers/dockerls.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('dockerfile') - -return installer.Installer:new { - 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' }, - }, -} diff --git a/lua/nvim-lsp-installer/installers/eslintls.lua b/lua/nvim-lsp-installer/installers/eslintls.lua deleted file mode 100644 index 13ddf94f..00000000 --- a/lua/nvim-lsp-installer/installers/eslintls.lua +++ /dev/null @@ -1,80 +0,0 @@ -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.Installer:new { - 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(string.format("open %q", open_doc.url)) - return {id = nil, result = true} - end, - ["eslint/confirmESLintExecution"] = function () - -- VSCode language servers have a policy to request explicit approval - -- before applying code changes. We just approve it immediately. - 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.lua b/lua/nvim-lsp-installer/installers/graphql.lua deleted file mode 100644 index 471eb3ba..00000000 --- a/lua/nvim-lsp-installer/installers/graphql.lua +++ /dev/null @@ -1,16 +0,0 @@ -local util = require('lspconfig.util') - -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('graphql') - -return installer.Installer:new { - 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'), - }, -} diff --git a/lua/nvim-lsp-installer/installers/html.lua b/lua/nvim-lsp-installer/installers/html.lua deleted file mode 100644 index 8e269e18..00000000 --- a/lua/nvim-lsp-installer/installers/html.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('html') - -return installer.Installer:new { - 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' }, - }, -} diff --git a/lua/nvim-lsp-installer/installers/jsonls.lua b/lua/nvim-lsp-installer/installers/jsonls.lua deleted file mode 100644 index 0298f5ae..00000000 --- a/lua/nvim-lsp-installer/installers/jsonls.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('json') - -return installer.Installer:new { - 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' }, - }, -} diff --git a/lua/nvim-lsp-installer/installers/pyright.lua b/lua/nvim-lsp-installer/installers/pyright.lua deleted file mode 100644 index a6684def..00000000 --- a/lua/nvim-lsp-installer/installers/pyright.lua +++ /dev/null @@ -1,13 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('python') - -return installer.Installer:new { - name = "pyright", - root_dir = root_dir, - install_cmd = [[npm install pyright]], - default_options = { - cmd = { root_dir .. '/node_modules/.bin/pyright-langserver', '--stdio' }, - on_attach = installer.common_on_attach, - }, -} diff --git a/lua/nvim-lsp-installer/installers/solargraph.lua b/lua/nvim-lsp-installer/installers/solargraph.lua deleted file mode 100644 index c227c2b3..00000000 --- a/lua/nvim-lsp-installer/installers/solargraph.lua +++ /dev/null @@ -1,34 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -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.Installer:new { - name = "solargraph", - 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' }, - } -} diff --git a/lua/nvim-lsp-installer/installers/sumneko_lua.lua b/lua/nvim-lsp-installer/installers/sumneko_lua.lua deleted file mode 100644 index 947ae276..00000000 --- a/lua/nvim-lsp-installer/installers/sumneko_lua.lua +++ /dev/null @@ -1,57 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -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.Installer:new { - 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"}, - 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/tsserver.lua b/lua/nvim-lsp-installer/installers/tsserver.lua deleted file mode 100644 index 87310e02..00000000 --- a/lua/nvim-lsp-installer/installers/tsserver.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('tsserver') - -return installer.Installer:new { - 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' }, - }, -} diff --git a/lua/nvim-lsp-installer/installers/vimls.lua b/lua/nvim-lsp-installer/installers/vimls.lua deleted file mode 100644 index 3e6786b7..00000000 --- a/lua/nvim-lsp-installer/installers/vimls.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('vim') - -return installer.Installer:new { - 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" }, - } -} diff --git a/lua/nvim-lsp-installer/installers/yamlls.lua b/lua/nvim-lsp-installer/installers/yamlls.lua deleted file mode 100644 index 5d68915a..00000000 --- a/lua/nvim-lsp-installer/installers/yamlls.lua +++ /dev/null @@ -1,12 +0,0 @@ -local installer = require('nvim-lsp-installer.installer') - -local root_dir = installer.get_server_root_path('yaml') - -return installer.Installer:new { - 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' }, - } -} diff --git a/lua/nvim-lsp-installer/server.lua b/lua/nvim-lsp-installer/server.lua new file mode 100644 index 00000000..5c71922b --- /dev/null +++ b/lua/nvim-lsp-installer/server.lua @@ -0,0 +1,167 @@ +local M = {} + +-- :'<,'>!sort +local _SERVERS = { + 'bashls', + 'cssls', + 'dockerls', + 'eslintls', + 'graphql', + 'html', + 'jsonls', + 'solargraph', + 'sumneko_lua', + 'tsserver', + 'vimls', + 'yamlls', +} + +local function escape_quotes(str) + return string.format("%q", str) +end + +local function get_server(server_name) + return pcall(require, 'nvim-lsp-installer.servers.' .. server_name) +end + +local function get_servers(server_names) + local result = {} + for _, server_name in pairs(server_names) do + local ok, server = get_server(server_name) + if not ok then + vim.api.nvim_err_writeln("Unable to find LSP server " .. server_name) + goto continue + end + result[server_name] = server + ::continue:: + end + return result +end + +function M.get_available_servers() + return vim.tbl_values(get_servers(_SERVERS)) +end + +function M.get_installed_servers() + return vim.tbl_filter( + function (server) + return server:is_installed() + end, + M.get_available_servers() + ) +end + +function M.get_uninstalled_servers() + return vim.tbl_filter( + function (server) + return not server:is_installed() + end, + M.get_available_servers() + ) +end + +function M.install(server_name) + local ok, server = get_server(server_name) + if not ok then + return vim.api.nvim_err_writeln("Unable to find LSP server " .. server_name) + end + local success, error = pcall(server.install, server) + if not success then + pcall(server.uninstall, server) + return vim.api.nvim_err_writeln("Failed to install " .. server_name .. ". Error=" .. vim.inspect(error)) + end +end + +function M.uninstall(server_name) + local ok, server = get_server(server_name) + if not ok then + return vim.api.nvim_err_writeln("Unable to find LSP server " .. server_name) + end + local success, error = pcall(server.uninstall, server) + if not success then + vim.api.nvim_err_writeln('Unable to uninstall ' .. server_name .. '. Error=' .. vim.inspect(error)) + return success + end + print("Successfully uninstalled " .. server_name) +end + +function M.get_server_root_path(server) + return vim.fn.stdpath('data') .. "/lsp_servers/" .. server +end + +M.Server = {} +M.Server.__index = M.Server + +---@class Server +function M.Server:new(opts) + return setmetatable({ + name = opts.name, + _install_cmd = opts.install_cmd, + _root_dir = opts.root_dir, + _default_options = opts.default_options, + _pre_install = opts.pre_install, + }, M.Server) +end + +function M.Server:setup(opts) + -- We require the lspconfig server here in order to do it as late as possible. + -- The reason for this is because once a lspconfig server has been imported, it's + -- automatically registered with lspconfig and causes it to show up in :LspInfo and whatnot. + require'lspconfig'[self.name].setup( + vim.tbl_deep_extend('force', self._default_options, opts) + ) +end + +function M.Server:is_installed() + return os.execute('test -d ' .. escape_quotes(self._root_dir)) == 0 +end + +function M.Server:create_root_dir() + if os.execute('mkdir -p ' .. escape_quotes(self._root_dir)) ~= 0 then + error('Could not create LSP server directory ' .. self._root_dir) + end +end + +function M.Server:install() + if self._pre_install then + self._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. + self:uninstall() + + self:create_root_dir() + + local shell = vim.o.shell + vim.o.shell = '/bin/bash' + vim.cmd [[new]] + vim.fn.termopen( + 'set -e;\n' .. self._install_cmd, + { + cwd = self._root_dir, + on_exit = function (_, exit_code) + if exit_code ~= 0 then + vim.api.nvim_err_writeln("Server installation failed for " .. self.name .. ". Exit code: " .. exit_code) + self:uninstall() + else + print("Successfully installed " .. self.name) + end + + end + } + ) + vim.o.shell = shell + vim.cmd([[startinsert]]) -- so that the buffer tails the term log nicely +end + +function M.Server:uninstall() + -- giggity + if os.execute('rm -rf ' .. escape_quotes(self._root_dir)) ~= 0 then + error('Could not remove LSP server directory ' .. self._root_dir) + end + +end + +return M diff --git a/lua/nvim-lsp-installer/servers/bashls.lua b/lua/nvim-lsp-installer/servers/bashls.lua new file mode 100644 index 00000000..224e8d23 --- /dev/null +++ b/lua/nvim-lsp-installer/servers/bashls.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('bash') + +return server.Server:new { + 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" }, + }, +} diff --git a/lua/nvim-lsp-installer/servers/cssls.lua b/lua/nvim-lsp-installer/servers/cssls.lua new file mode 100644 index 00000000..53bb6378 --- /dev/null +++ b/lua/nvim-lsp-installer/servers/cssls.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('css') + +return server.Server:new { + 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' }, + }, +} diff --git a/lua/nvim-lsp-installer/servers/dockerls.lua b/lua/nvim-lsp-installer/servers/dockerls.lua new file mode 100644 index 00000000..dbe4645e --- /dev/null +++ b/lua/nvim-lsp-installer/servers/dockerls.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('dockerfile') + +return server.Server:new { + 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' }, + }, +} diff --git a/lua/nvim-lsp-installer/servers/eslintls.lua b/lua/nvim-lsp-installer/servers/eslintls.lua new file mode 100644 index 00000000..b8f0f448 --- /dev/null +++ b/lua/nvim-lsp-installer/servers/eslintls.lua @@ -0,0 +1,80 @@ +local lspconfig = require'lspconfig' +local configs = require'lspconfig/configs' + +local server = require'nvim-lsp-installer.server' + +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 = server.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 server.Server:new { + 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(string.format("open %q", open_doc.url)) + return {id = nil, result = true} + end, + ["eslint/confirmESLintExecution"] = function () + -- VSCode language servers have a policy to request explicit approval + -- before applying code changes. We just approve it immediately. + 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/servers/graphql.lua b/lua/nvim-lsp-installer/servers/graphql.lua new file mode 100644 index 00000000..1728e81e --- /dev/null +++ b/lua/nvim-lsp-installer/servers/graphql.lua @@ -0,0 +1,16 @@ +local util = require('lspconfig.util') + +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('graphql') + +return server.Server:new { + 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'), + }, +} diff --git a/lua/nvim-lsp-installer/servers/html.lua b/lua/nvim-lsp-installer/servers/html.lua new file mode 100644 index 00000000..36acc429 --- /dev/null +++ b/lua/nvim-lsp-installer/servers/html.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('html') + +return server.Server:new { + 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' }, + }, +} diff --git a/lua/nvim-lsp-installer/servers/jsonls.lua b/lua/nvim-lsp-installer/servers/jsonls.lua new file mode 100644 index 00000000..e856f50f --- /dev/null +++ b/lua/nvim-lsp-installer/servers/jsonls.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('json') + +return server.Server:new { + 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' }, + }, +} diff --git a/lua/nvim-lsp-installer/servers/pyright.lua b/lua/nvim-lsp-installer/servers/pyright.lua new file mode 100644 index 00000000..e356deb0 --- /dev/null +++ b/lua/nvim-lsp-installer/servers/pyright.lua @@ -0,0 +1,13 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('python') + +return server.Server:new { + name = "pyright", + root_dir = root_dir, + install_cmd = [[npm install pyright]], + default_options = { + cmd = { root_dir .. '/node_modules/.bin/pyright-langserver', '--stdio' }, + on_attach = server.common_on_attach, + }, +} diff --git a/lua/nvim-lsp-installer/servers/solargraph.lua b/lua/nvim-lsp-installer/servers/solargraph.lua new file mode 100644 index 00000000..c9f99e7c --- /dev/null +++ b/lua/nvim-lsp-installer/servers/solargraph.lua @@ -0,0 +1,34 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.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 server.Server:new { + name = "solargraph", + 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' }, + } +} diff --git a/lua/nvim-lsp-installer/servers/sumneko_lua.lua b/lua/nvim-lsp-installer/servers/sumneko_lua.lua new file mode 100644 index 00000000..81ac2bcb --- /dev/null +++ b/lua/nvim-lsp-installer/servers/sumneko_lua.lua @@ -0,0 +1,57 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.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 server.Server:new { + 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"}, + 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/servers/tsserver.lua b/lua/nvim-lsp-installer/servers/tsserver.lua new file mode 100644 index 00000000..0294dc79 --- /dev/null +++ b/lua/nvim-lsp-installer/servers/tsserver.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('tsserver') + +return server.Server:new { + 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' }, + }, +} diff --git a/lua/nvim-lsp-installer/servers/vimls.lua b/lua/nvim-lsp-installer/servers/vimls.lua new file mode 100644 index 00000000..94041007 --- /dev/null +++ b/lua/nvim-lsp-installer/servers/vimls.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('vim') + +return server.Server:new { + 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" }, + } +} diff --git a/lua/nvim-lsp-installer/servers/yamlls.lua b/lua/nvim-lsp-installer/servers/yamlls.lua new file mode 100644 index 00000000..03f1e75a --- /dev/null +++ b/lua/nvim-lsp-installer/servers/yamlls.lua @@ -0,0 +1,12 @@ +local server = require('nvim-lsp-installer.server') + +local root_dir = server.get_server_root_path('yaml') + +return server.Server:new { + 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' }, + } +} diff --git a/plugin/nvim-lsp-installer.vim b/plugin/nvim-lsp-installer.vim index 34277863..48f6a96b 100644 --- a/plugin/nvim-lsp-installer.vim +++ b/plugin/nvim-lsp-installer.vim @@ -4,38 +4,40 @@ let g:loaded_nvim_lsp_installer = 1 let s:save_cpo = &cpo set cpo&vim +function! s:MapServerName(servers) abort + return map(a:servers, {_, val -> val.name}) +endfunction + function! s:LspInstallCompletion(...) abort - return join(luaeval("require'nvim-lsp-installer'.get_available_servers()"), "\n") + return join(s:MapServerName(luaeval("require'nvim-lsp-installer'.get_available_servers()")), "\n") endfunction function! s:LspUninstallCompletion(...) abort - return join( - \ map(luaeval("require'nvim-lsp-installer'.get_installed_servers()"), {_, val -> val.name}), - \ "\n") + return join(s:MapServerName(luaeval("require'nvim-lsp-installer'.get_installed_servers()")), "\n") endfunction -function! s:LspInstall(server) abort - call luaeval("require'nvim-lsp-installer'.install(_A)", a:server) +function! s:LspInstall(server_name) abort + call luaeval("require'nvim-lsp-installer'.install(_A)", a:server_name) endfunction function! s:LspInstallAll() abort - for server in luaeval("require'nvim-lsp-installer'.get_uninstalled_servers()") - call luaeval("require'nvim-lsp-installer'.install(_A)", server) + for server_name in s:MapServerName(luaeval("require'nvim-lsp-installer'.get_uninstalled_servers()")) + call luaeval("require'nvim-lsp-installer'.install(_A)", server_name) endfor endfunction -function! s:LspUninstall(server) abort - call luaeval("require'nvim-lsp-installer'.uninstall(_A)", a:server) +function! s:LspUninstall(server_name) abort + call luaeval("require'nvim-lsp-installer'.uninstall(_A)", a:server_name) endfunction function! s:LspUninstallAll() abort - for server in luaeval("require'nvim-lsp-installer'.get_installed_servers()") + for server in s:MapServerName(luaeval("require'nvim-lsp-installer'.get_installed_servers()")) call s:LspUninstall(server) endfor endfunction function! s:LspPrintInstalled() abort - echo map(luaeval("require'nvim-lsp-installer'.get_installed_servers()"), {_, val -> val.name}) + echo s:MapServerName(luaeval("require'nvim-lsp-installer'.get_installed_servers()")) endfunction command! -nargs=1 -complete=custom,s:LspInstallCompletion LspInstall exe s:LspInstall("") -- cgit v1.2.3-70-g09d2