diff options
Diffstat (limited to 'lua/nvim-lsp-installer/server.lua')
| -rw-r--r-- | lua/nvim-lsp-installer/server.lua | 167 |
1 files changed, 167 insertions, 0 deletions
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 |
