aboutsummaryrefslogtreecommitdiffstats
path: root/lua/nvim-lsp-installer/server.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/nvim-lsp-installer/server.lua')
-rw-r--r--lua/nvim-lsp-installer/server.lua167
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