manager.lua 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. local M = {}
  2. local Log = require "lvim.core.log"
  3. local lvim_lsp_utils = require "lvim.lsp.utils"
  4. ---Resolve the configuration for a server by merging with the default config
  5. ---@param server_name string
  6. ---@vararg any config table [optional]
  7. ---@return table
  8. local function resolve_config(server_name, ...)
  9. local defaults = {
  10. on_attach = require("lvim.lsp").common_on_attach,
  11. on_init = require("lvim.lsp").common_on_init,
  12. on_exit = require("lvim.lsp").common_on_exit,
  13. capabilities = require("lvim.lsp").common_capabilities(),
  14. }
  15. local has_custom_provider, custom_config = pcall(require, "lvim/lsp/providers/" .. server_name)
  16. if has_custom_provider then
  17. Log:debug("Using custom configuration for requested server: " .. server_name)
  18. defaults = vim.tbl_deep_extend("force", defaults, custom_config)
  19. end
  20. defaults = vim.tbl_deep_extend("force", defaults, ...)
  21. return defaults
  22. end
  23. -- manually start the server and don't wait for the usual filetype trigger from lspconfig
  24. local function buf_try_add(server_name, bufnr)
  25. bufnr = bufnr or vim.api.nvim_get_current_buf()
  26. require("lspconfig")[server_name].manager.try_add_wrapper(bufnr)
  27. end
  28. -- check if the manager autocomd has already been configured since some servers can take a while to initialize
  29. -- this helps guarding against a data-race condition where a server can get configured twice
  30. -- which seems to occur only when attaching to single-files
  31. local function client_is_configured(server_name, ft)
  32. ft = ft or vim.bo.filetype
  33. local active_autocmds = vim.split(vim.fn.execute("autocmd FileType " .. ft), "\n")
  34. for _, result in ipairs(active_autocmds) do
  35. if result:match(server_name) then
  36. Log:debug(string.format("[%q] is already configured", server_name))
  37. return true
  38. end
  39. end
  40. return false
  41. end
  42. local function launch_server(server_name, config)
  43. pcall(function()
  44. require("lspconfig")[server_name].setup(config)
  45. buf_try_add(server_name)
  46. end)
  47. end
  48. ---Setup a language server by providing a name
  49. ---@param server_name string name of the language server
  50. ---@param user_config table? when available it will take predence over any default configurations
  51. function M.setup(server_name, user_config)
  52. vim.validate { name = { server_name, "string" } }
  53. user_config = user_config or {}
  54. if lvim_lsp_utils.is_client_active(server_name) or client_is_configured(server_name) then
  55. return
  56. end
  57. local servers = require "nvim-lsp-installer.servers"
  58. local server_available, server = servers.get_server(server_name)
  59. if not server_available then
  60. local config = resolve_config(server_name, user_config)
  61. launch_server(server_name, config)
  62. return
  63. end
  64. local install_in_progress = false
  65. if not server:is_installed() then
  66. if lvim.lsp.automatic_servers_installation then
  67. Log:debug "Automatic server installation detected"
  68. server:install()
  69. install_in_progress = true
  70. else
  71. Log:debug(server.name .. " is not managed by the automatic installer")
  72. end
  73. end
  74. server:on_ready(function()
  75. if install_in_progress then
  76. vim.notify(string.format("Installation complete for [%s] server", server.name), vim.log.levels.INFO)
  77. end
  78. install_in_progress = false
  79. local config = resolve_config(server_name, server:get_default_options(), user_config)
  80. launch_server(server_name, config)
  81. end)
  82. end
  83. return M