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

refactor: more consistent autocmds (#2133)

kylo252 3 роки тому
батько
коміт
238e43e5b3

+ 64 - 19
lua/lvim/core/autocmds.lua

@@ -86,16 +86,12 @@ function M.enable_format_on_save(opts)
 end
 
 function M.disable_format_on_save()
-  M.remove_augroup "format_on_save"
+  M.disable_augroup "format_on_save"
   Log:debug "disabled format-on-save"
 end
 
 function M.configure_format_on_save()
   if lvim.format_on_save then
-    if vim.fn.exists "#format_on_save#BufWritePre" == 1 then
-      M.remove_augroup "format_on_save"
-      Log:debug "reloading format-on-save configuration"
-    end
     local opts = get_format_on_save_opts()
     M.enable_format_on_save(opts)
   else
@@ -112,24 +108,73 @@ function M.toggle_format_on_save()
   end
 end
 
-function M.remove_augroup(name)
-  if vim.fn.exists("#" .. name) == 1 then
-    vim.cmd("au! " .. name)
-  end
+function M.enable_lsp_document_highlight(client_id)
+  M.define_augroups({
+    lsp_document_highlight = {
+      {
+        "CursorHold",
+        "<buffer>",
+        string.format("lua require('lvim.lsp.utils').conditional_document_highlight(%d)", client_id),
+      },
+      {
+        "CursorMoved",
+        "<buffer>",
+        "lua vim.lsp.buf.clear_references()",
+      },
+    },
+  }, true)
+end
+
+function M.disable_lsp_document_highlight()
+  M.disable_augroup "lsp_document_highlight"
+end
+
+function M.enable_code_lens_refresh()
+  M.define_augroups({
+    lsp_code_lens_refresh = {
+      {
+        "InsertLeave ",
+        "<buffer>",
+        "lua vim.lsp.codelens.refresh()",
+      },
+      {
+        "InsertLeave ",
+        "<buffer>",
+        "lua vim.lsp.codelens.display()",
+      },
+    },
+  }, true)
 end
 
-function M.define_augroups(definitions) -- {{{1
-  -- Create autocommand groups based on the passed definitions
-  --
-  -- The key will be the name of the group, and each definition
-  -- within the group should have:
-  --    1. Trigger
-  --    2. Pattern
-  --    3. Text
-  -- just like how they would normally be defined from Vim itself
+function M.disable_code_lens_refresh()
+  M.disable_augroup "lsp_code_lens_refresh"
+end
+
+--- Disable autocommand groups if it exists
+--- This is more reliable than trying to delete the augroup itself
+---@param name string the augroup name
+function M.disable_augroup(name)
+  -- defer the function in case the autocommand is still in-use
+  vim.schedule(function()
+    if vim.fn.exists("#" .. name) == 1 then
+      vim.cmd("augroup " .. name)
+      vim.cmd "autocmd!"
+      vim.cmd "augroup END"
+    end
+  end)
+end
+
+--- Create autocommand groups based on the passed definitions
+---@param definitions table contains trigger, pattern and text. The key will be used as a group name
+---@param buffer boolean indicate if the augroup should be local to the buffer
+function M.define_augroups(definitions, buffer)
   for group_name, definition in pairs(definitions) do
     vim.cmd("augroup " .. group_name)
-    vim.cmd "autocmd!"
+    if buffer then
+      vim.cmd [[autocmd! * <buffer>]]
+    else
+      vim.cmd [[autocmd!]]
+    end
 
     for _, def in pairs(definition) do
       local command = table.concat(vim.tbl_flatten { "autocmd", def }, " ")

+ 14 - 24
lua/lvim/lsp/init.lua

@@ -1,24 +1,13 @@
 local M = {}
 local Log = require "lvim.core.log"
 local utils = require "lvim.utils"
+local autocmds = require "lvim.core.autocmds"
 
 local function lsp_highlight_document(client)
   if lvim.lsp.document_highlight == false then
     return -- we don't need further
   end
-  -- Set autocommands conditional on server_capabilities
-  if client.resolved_capabilities.document_highlight then
-    vim.api.nvim_exec(
-      [[
-      augroup lsp_document_highlight
-        autocmd! * <buffer>
-        autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()
-        autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
-      augroup END
-    ]],
-      false
-    )
-  end
+  autocmds.enable_lsp_document_highlight(client.id)
 end
 
 local function lsp_code_lens_refresh(client)
@@ -27,16 +16,7 @@ local function lsp_code_lens_refresh(client)
   end
 
   if client.resolved_capabilities.code_lens then
-    vim.api.nvim_exec(
-      [[
-      augroup lsp_code_lens_refresh
-        autocmd! * <buffer>
-        autocmd InsertLeave <buffer> lua vim.lsp.codelens.refresh()
-        autocmd InsertLeave <buffer> lua vim.lsp.codelens.display()
-      augroup END
-    ]],
-      false
-    )
+    autocmds.enable_code_lens_refresh()
   end
 end
 
@@ -101,6 +81,15 @@ local function select_default_formater(client)
   end
 end
 
+function M.common_on_exit(_, _)
+  if lvim.lsp.document_highlight then
+    autocmds.disable_lsp_document_highlight()
+  end
+  if lvim.lsp.code_lens_refresh then
+    autocmds.disable_code_lens_refresh()
+  end
+end
+
 function M.common_on_init(client, bufnr)
   if lvim.lsp.on_init_callback then
     lvim.lsp.on_init_callback(client, bufnr)
@@ -132,6 +121,7 @@ function M.get_common_opts()
   return {
     on_attach = M.common_on_attach,
     on_init = M.common_on_init,
+    on_exit = M.common_on_exit,
     capabilities = M.common_capabilities(),
   }
 end
@@ -171,7 +161,7 @@ function M.setup()
 
   require("lvim.lsp.null-ls").setup()
 
-  require("lvim.core.autocmds").configure_format_on_save()
+  autocmds.configure_format_on_save()
 end
 
 return M

+ 1 - 0
lua/lvim/lsp/manager.lua

@@ -24,6 +24,7 @@ local function resolve_config(name, user_config)
   local config = {
     on_attach = require("lvim.lsp").common_on_attach,
     on_init = require("lvim.lsp").common_on_init,
+    on_exit = require("lvim.lsp").common_on_exit,
     capabilities = require("lvim.lsp").common_capabilities(),
   }
 

+ 10 - 0
lua/lvim/lsp/utils.lua

@@ -76,4 +76,14 @@ function M.get_all_supported_filetypes()
   return vim.tbl_keys(lsp_installer_filetypes or {})
 end
 
+function M.conditional_document_highlight(id)
+  local client_ok, method_supported = pcall(function()
+    return vim.lsp.get_client_by_id(id).resolved_capabilities.document_highlight
+  end)
+  if not client_ok or not method_supported then
+    return
+  end
+  vim.lsp.buf.document_highlight()
+end
+
 return M

+ 4 - 4
lua/lvim/utils/hooks.lua

@@ -21,14 +21,14 @@ function M.run_on_packer_complete()
   require("lvim.plugin-loader").recompile()
   -- forcefully activate nvim-web-devicons
   require("nvim-web-devicons").set_up_highlights()
+  if package.loaded["lspconfig"] then
+    vim.cmd [[ LspStart ]]
+  end
   Log:info "Reloaded configuration"
 end
 
 function M.run_post_reload()
   Log:debug "Starting post-reload hook"
-  if package.loaded["lspconfig"] then
-    vim.cmd [[ LspRestart ]]
-  end
 
   M.reset_cache()
   require("lvim.plugin-loader").ensure_installed()
@@ -68,7 +68,7 @@ function M.run_post_update()
       -- TODO: add a changelog
       vim.notify("Update complete", vim.log.levels.INFO)
       if package.loaded["lspconfig"] then
-        vim.cmd [[ LspRestart ]]
+        vim.cmd [[ LspStart ]]
       end
     end)
   end