diff --git a/lua/nvim-lsp-installer/middleware.lua b/lua/nvim-lsp-installer/middleware.lua index 44af9f0f7e..04ffe2a94a 100644 --- a/lua/nvim-lsp-installer/middleware.lua +++ b/lua/nvim-lsp-installer/middleware.lua @@ -1,4 +1,5 @@ local util = require "lspconfig.util" +local _ = require "nvim-lsp-installer.core.functional" local notify = require "nvim-lsp-installer.notify" local servers = require "nvim-lsp-installer.servers" local settings = require "nvim-lsp-installer.settings" @@ -38,6 +39,17 @@ local function should_auto_install(server_name) return false end +local registered_server_hooks = {} + +---@param server_name string +---@param fn fun(config: table) +function M.register_server_hook(server_name, fn) + if not registered_server_hooks[server_name] then + registered_server_hooks[server_name] = {} + end + table.insert(registered_server_hooks[server_name], fn) +end + function M.register_lspconfig_hook() util.on_setup = util.add_hook_before(util.on_setup, function(config) local ok, server = servers.get_server(config.name) @@ -49,6 +61,15 @@ function M.register_lspconfig_hook() server:install() end end + + if registered_server_hooks[config.name] then + _.each(function(fn) + local ok, err = pcall(fn, config) + if not ok then + notify(err, vim.log.levels.ERROR) + end + end, registered_server_hooks[config.name]) + end end) end diff --git a/lua/nvim-lsp-installer/servers/pylsp/README.md b/lua/nvim-lsp-installer/servers/pylsp/README.md index 426cf7fd60..2434bb4b6d 100644 --- a/lua/nvim-lsp-installer/servers/pylsp/README.md +++ b/lua/nvim-lsp-installer/servers/pylsp/README.md @@ -10,8 +10,7 @@ In order for these plugins to work with the `pylsp` server managed by this plugi :PylspInstall pyls-flake8 pylsp-mypy pyls-isort ``` -The `:PylspInstall` command will only be available once the `pylsp` server is started (this happens once you've opened a -Python file, for example). +The `:PylspInstall` command will only be available once the `pylsp` server has been set up. **Note that these extra pylsp plugins will not be reinstalled if you update/reinstall the `pylsp` server, you will have to manage them manually.** diff --git a/lua/nvim-lsp-installer/servers/pylsp/init.lua b/lua/nvim-lsp-installer/servers/pylsp/init.lua index 54e6861df6..4f0a01d1db 100644 --- a/lua/nvim-lsp-installer/servers/pylsp/init.lua +++ b/lua/nvim-lsp-installer/servers/pylsp/init.lua @@ -1,21 +1,55 @@ +local a = require "nvim-lsp-installer.core.async" +local _ = require "nvim-lsp-installer.core.functional" local server = require "nvim-lsp-installer.server" local pip3 = require "nvim-lsp-installer.core.managers.pip3" local process = require "nvim-lsp-installer.core.process" local notify = require "nvim-lsp-installer.notify" - -function _G.lsp_installer_pylsp_install_completion() - return table.concat({ - "pyls-flake8", - "pylsp-mypy", - "pyls-spyder", - "pyls-isort", - "python-lsp-black", - "pyls-memestra", - "pylsp-rope", - }, "\n") -end +local middleware = require "nvim-lsp-installer.middleware" +local spawn = require "nvim-lsp-installer.core.spawn" return function(name, root_dir) + middleware.register_server_hook(name, function() + vim.api.nvim_create_user_command( + "PylspInstall", + a.scope(function(opts) + local plugins = opts.fargs + local plugins_str = table.concat(plugins, ", ") + notify(("Installing %s..."):format(plugins_str)) + local result = spawn.pip { + "install", + "-U", + "--disable-pip-version-check", + plugins, + stdio_sink = process.simple_sink(), + with_paths = { pip3.venv_path(root_dir) }, + } + if vim.in_fast_event() then + a.scheduler() + end + result + :on_success(function() + notify(("Successfully installed pylsp plugins %s"):format(plugins_str)) + end) + :on_failure(function() + notify("Failed to install requested pylsp plugins.", vim.log.levels.ERROR) + end) + end), + { + desc = "[nvim-lsp-installer] Installs the provided packages in the same venv as pylsp.", + nargs = "+", + complete = _.always { + "pyls-flake8", + "pylsp-mypy", + "pyls-spyder", + "pyls-isort", + "python-lsp-black", + "pyls-memestra", + "pylsp-rope", + }, + } + ) + end) + return server.Server:new { name = name, root_dir = root_dir, @@ -24,34 +58,6 @@ return function(name, root_dir) installer = pip3.packages { "python-lsp-server[all]" }, default_options = { cmd_env = pip3.env(root_dir), - commands = { - PylspInstall = { - function(...) - -- `nargs+` requires at least one argument -> no empty table - local plugins = { ... } - local plugins_str = table.concat(plugins, ", ") - notify(("Installing %q..."):format(plugins_str)) - process.spawn( - "pip", - { - args = vim.list_extend({ "install", "-U", "--disable-pip-version-check" }, plugins), - stdio_sink = process.simple_sink(), - env = process.graft_env(pip3.env(root_dir)), - }, - vim.schedule_wrap(function(success) - if success then - notify(("Successfully installed %q"):format(plugins_str)) - else - notify("Failed to install requested plugins.", vim.log.levels.ERROR) - end - end) - ) - end, - description = "Installs the provided packages in the same venv as pylsp.", - ["nargs=+"] = true, - ["complete=custom,v:lua.lsp_installer_pylsp_install_completion"] = true, - }, - }, }, } end diff --git a/lua/nvim-lsp-installer/servers/tflint/README.md b/lua/nvim-lsp-installer/servers/tflint/README.md index 359a616536..51298d69b8 100644 --- a/lua/nvim-lsp-installer/servers/tflint/README.md +++ b/lua/nvim-lsp-installer/servers/tflint/README.md @@ -2,8 +2,13 @@ ## Installing TFLint plugins -To install TFLint plugins, using the same installation of TFLint as nvim-lsp-installer, you may run the `:TFLintInit` -command. This command assumes that: +TFLint has [third party plugins](https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md) which are not installed by default. -1. there exists a `.tflint.hcl` file in neovim's current working directory. -1. you've called `server:setup(opts)` for `tflint` +To install TFLint plugins, there's a convenient `:TFLintInit` command that does this for you. It will use Neovim's +current working directory to locate the plugins to install (according to `tflint --init`): + +``` +:TFLintInit +``` + +The `:TFLintInit` command will only be available once the `tflint` server has been set up. diff --git a/lua/nvim-lsp-installer/servers/tflint/init.lua b/lua/nvim-lsp-installer/servers/tflint/init.lua index 421333c52e..bf370fe3cc 100644 --- a/lua/nvim-lsp-installer/servers/tflint/init.lua +++ b/lua/nvim-lsp-installer/servers/tflint/init.lua @@ -1,14 +1,44 @@ +local a = require "nvim-lsp-installer.core.async" +local notify = require "nvim-lsp-installer.notify" +local spawn = require "nvim-lsp-installer.core.spawn" +local process = require "nvim-lsp-installer.core.process" local server = require "nvim-lsp-installer.server" local functional = require "nvim-lsp-installer.core.functional" -local a = require "nvim-lsp-installer.core.async" local platform = require "nvim-lsp-installer.core.platform" local github = require "nvim-lsp-installer.core.managers.github" -local spawn = require "nvim-lsp-installer.core.spawn" -local process = require "nvim-lsp-installer.core.process" +local middleware = require "nvim-lsp-installer.middleware" local coalesce, when = functional.coalesce, functional.when return function(name, root_dir) + middleware.register_server_hook(name, function() + vim.api.nvim_create_user_command( + "TFLintInit", + a.scope(function() + notify "Installing TFLint plugins…" + local result = spawn.tflint { + "--init", + cwd = vim.loop.cwd(), + stdio_sink = process.simple_sink(), + with_paths = { root_dir }, + } + if vim.in_fast_event() then + a.scheduler() + end + result + :on_success(function() + notify "Successfully installed TFLint plugins." + end) + :on_failure(function() + notify("Failed to install TFLint plugins.", vim.log.levels.ERROR) + end) + end), + { + desc = "[nvim-lsp-installer] Runs tflint --init in the current directory.", + } + ) + end) + return server.Server:new { name = name, root_dir = root_dir, @@ -31,33 +61,6 @@ return function(name, root_dir) cmd_env = { PATH = process.extend_path { root_dir }, }, - commands = { - TFLintInit = { - a.scope(function() - local notify = require "nvim-lsp-installer.notify" - - notify "Installing TFLint plugins…" - spawn.tflint({ - "--init", - cwd = vim.loop.getcwd(), - with_paths = { root_dir }, - }) - :on_success(function() - if vim.in_fast_event() then - a.scheduler() - end - notify "Successfully installed TFLint plugins." - end) - :on_failure(function() - if vim.in_fast_event() then - a.scheduler() - end - notify "Failed to install TFLint plugins." - end) - end), - description = "Runs tflint --init in the current working directory.", - }, - }, }, } end