Переглянути джерело

fix(lsp): avoid data-race on server:install() (#1863)

kylo252 3 роки тому
батько
коміт
95d8127f31
3 змінених файлів з 28 додано та 68 видалено
  1. 0 5
      lua/lvim/core/autocmds.lua
  2. 28 16
      lua/lvim/lsp/manager.lua
  3. 0 47
      lua/lvim/utils/ft.lua

+ 0 - 5
lua/lvim/core/autocmds.lua

@@ -6,11 +6,6 @@ function M.load_augroups()
 
   return {
     _general_settings = {
-      {
-        "Filetype",
-        "*",
-        "lua require('lvim.utils.ft').do_filetype(vim.fn.expand(\"<amatch>\"))",
-      },
       { "FileType", "qf,help,man", "nnoremap <silent> <buffer> q :close<CR>" },
       {
         "TextYankPost",

+ 28 - 16
lua/lvim/lsp/manager.lua

@@ -39,6 +39,12 @@ local function resolve_config(name, user_config)
   return config
 end
 
+-- manually start the server and don't wait for the usual filetype trigger from lspconfig
+local function buf_try_add(server_name, bufnr)
+  bufnr = bufnr or vim.api.nvim_get_current_buf()
+  require("lspconfig")[server_name].manager.try_add(bufnr)
+end
+
 ---Setup a language server by providing a name
 ---@param server_name string name of the language server
 ---@param user_config table [optional] when available it will take predence over any default configurations
@@ -48,32 +54,38 @@ function M.setup(server_name, user_config)
   if lvim_lsp_utils.is_client_active(server_name) then
     return
   end
+  local servers = require "nvim-lsp-installer.servers"
 
   local config = resolve_config(server_name, user_config)
-  local server_available, requested_server = require("nvim-lsp-installer.servers").get_server(server_name)
+  local server_available, requested_server = servers.get_server(server_name)
 
-  local function ensure_installed(server)
-    if server:is_installed() then
-      return true
-    end
-    if not lvim.lsp.automatic_servers_installation then
-      Log:debug(server.name .. " is not managed by the automatic installer")
-      return false
+  if server_available then
+    local install_notification = false
+
+    if not requested_server:is_installed() then
+      if lvim.lsp.automatic_servers_installation then
+        Log:debug "Automatic server installation detected"
+        requested_server:install()
+        install_notification = true
+      else
+        Log:debug(requested_server.name .. " is not managed by the automatic installer")
+      end
     end
-    Log:debug(string.format("Installing [%s]", server.name))
-    server:install()
-    vim.schedule(function()
-      vim.cmd [[LspStart]]
-    end)
-  end
 
-  if server_available and ensure_installed(requested_server) then
-    requested_server:setup(config)
+    requested_server:on_ready(function()
+      if install_notification then
+        vim.notify(string.format("Installation complete for [%s] server", requested_server.name), vim.log.levels.INFO)
+      end
+      install_notification = false
+      requested_server:setup(config)
+      buf_try_add(server_name)
+    end)
   else
     -- since it may not be installed, don't attempt to configure the LSP unless there is a custom provider
     local has_custom_provider, _ = pcall(require, "lvim/lsp/providers/" .. server_name)
     if has_custom_provider then
       require("lspconfig")[server_name].setup(config)
+      buf_try_add(server_name)
     end
   end
 end

+ 0 - 47
lua/lvim/utils/ft.lua

@@ -1,47 +0,0 @@
--- Here be dragons
--- Opening files with telescope will not start LSP without this
-local ft = {}
-
-ft.find_lua_ftplugins = function(filetype)
-  local patterns = {
-    string.format("ftplugin/%s.lua", filetype),
-
-    -- Looks like we don't need this, because the first one works
-    -- string.format("after/ftplugin/%s.lua", filetype),
-  }
-
-  local result = {}
-  for _, pat in ipairs(patterns) do
-    vim.list_extend(result, vim.api.nvim_get_runtime_file(pat, true))
-  end
-
-  return result
-end
-
-ft.do_filetype = function(filetype)
-  local ftplugins = ft.find_lua_ftplugins(filetype)
-
-  local f_env = setmetatable({
-    -- Override print, so the prints still go through, otherwise it's confusing for people
-    print = vim.schedule_wrap(print),
-  }, {
-    -- Buf default back read/write to whatever is going on in the global landscape
-    __index = _G,
-    __newindex = _G,
-  })
-
-  for _, file in ipairs(ftplugins) do
-    local f = loadfile(file)
-    if not f then
-      vim.api.nvim_err_writeln("Unable to load file: " .. file)
-    else
-      local ok, msg = pcall(setfenv(f, f_env))
-
-      if not ok then
-        vim.api.nvim_err_writeln("Error while processing file: " .. file .. "\n" .. msg)
-      end
-    end
-  end
-end
-
-return ft