diff --git a/lua/LspUI/lib/util.lua b/lua/LspUI/lib/util.lua index b62eecf..5024411 100644 --- a/lua/LspUI/lib/util.lua +++ b/lua/LspUI/lib/util.lua @@ -58,20 +58,21 @@ end -- execute once --- @param callback function -M.exec_once = function(callback) +function M.exec_once(callback) local is_exec = false return function(...) - if not is_exec then - callback(...) - is_exec = true + if is_exec then + return end + callback(...) + is_exec = true end end -- debounce --- @param func function ---@param delay integer -M.debounce = function(func, delay) +function M.debounce(func, delay) local timer = nil return function(...) local args = { ... } diff --git a/lua/LspUI/lightbulb/init.lua b/lua/LspUI/lightbulb/init.lua index 94c4180..fc1ff87 100644 --- a/lua/LspUI/lightbulb/init.lua +++ b/lua/LspUI/lightbulb/init.lua @@ -10,12 +10,8 @@ local M = {} local is_initialized = false -- init for lightbulb -M.init = function() - if not config.options.lightbulb.enable then - return - end - - if is_initialized then +function M.init() + if (not config.options.lightbulb.enable) or is_initialized then return end @@ -30,12 +26,12 @@ M.init = function() end -- run for lightbulb -M.run = function() +function M.run() lib_notify.Info("lightbulb has no run func") end -- deinit for lightbulb -M.deinit = function() +function M.deinit() if not is_initialized then return end diff --git a/lua/LspUI/lightbulb/util.lua b/lua/LspUI/lightbulb/util.lua index 3a85c15..63a7baa 100644 --- a/lua/LspUI/lightbulb/util.lua +++ b/lua/LspUI/lightbulb/util.lua @@ -10,13 +10,12 @@ local lib_util = require("LspUI.lib.util") local M = {} -local attach_autocmd_id = -1 -local autocmd_list = {} +local autogroup_name = "Lspui_lightBulb" -- get all valid clients for lightbulb --- @param buffer_id integer --- @return vim.lsp.Client[]|nil clients array or nil -M.get_clients = function(buffer_id) +function M.get_clients(buffer_id) local clients = lsp.get_clients({ bufnr = buffer_id, method = code_action_feature }) if vim.tbl_isempty(clients) then @@ -29,7 +28,7 @@ end --- @param buffer_id integer buffer's id --- @param line integer the line number, and this will be set as sign id --- @return integer? sign_identifier sign's identifier, -1 means failing -M.render = function(buffer_id, line) +function M.render(buffer_id, line) if not api.nvim_buf_is_valid(buffer_id) then return end @@ -45,14 +44,14 @@ M.render = function(buffer_id, line) end -- clear sign -M.clear_render = function() +function M.clear_render() -- TODO:Do you need to add pcall here??? fn.sign_unplace(global.lightbulb.sign_group) end -- register the sign -- note: this func only can be called once! -M.register_sign = function() +function M.register_sign() fn.sign_define( global.lightbulb.sign_name, { text = config.options.lightbulb.icon } @@ -60,14 +59,14 @@ M.register_sign = function() end -- unregister the sign -M.unregister_sign = function() +function M.unregister_sign() fn.sign_undefine(global.lightbulb.sign_name) end -- this function will request all lsp clients --- @param buffer_id integer buffer's id --- @param callback function callback is a function, has a param boolean -M.request = function(buffer_id, callback) +function M.request(buffer_id, callback) -- this buffer id maybe invalid if not api.nvim_buf_is_valid(buffer_id) then return @@ -88,49 +87,49 @@ M.request = function(buffer_id, callback) } params.context = context - -- which commented below is the old logic - -- lsp.buf_request_all(buffer_id, code_action_feature, params, function(results) - -- local has_action = false - -- for _, result in pairs(results or {}) do - -- if result.result and type(result.result) == "table" and next(result.result) ~= nil then - -- has_action = true - -- break - -- end - -- end - -- if has_action then - -- callback(true) - -- else - -- callback(false) - -- end - -- end) + -- reduce a little calculations + local __callback = lib_util.exec_once(callback) - -- new logic, reduce a little calculations - local new_callback = lib_util.exec_once(callback) -- here will Check for new content + -- TODO: maybe we can add more integreation if config.options.code_action.gitsigns then local status, gitsigns = pcall(require, "gitsigns") - if status then - local gitsigns_actions = gitsigns.get_actions() - if gitsigns_actions and not vim.tbl_isempty(gitsigns_actions) then - new_callback(true) - return - end + if not status then + goto _continue + end + local gitsigns_actions = gitsigns.get_actions() + if gitsigns_actions and not vim.tbl_isempty(gitsigns_actions) then + __callback(true) + return end + ::_continue:: end - if - not vim.tbl_isempty( - code_action_register.handle(params.textDocument.uri, params.range) - ) - then - new_callback(true) + + -- stylua: ignore + local register_res =code_action_register.handle(params.textDocument.uri, params.range) + + if not vim.tbl_isempty(register_res) then + __callback(true) return end local clients = M.get_clients(buffer_id) local tmp_number = 0 + for _, client in pairs(clients or {}) do - client.request(code_action_feature, params, function(err, result, _, _) + local _tmp = function(err, result, _, _) tmp_number = tmp_number + 1 + + if + err == nil + and result + and type(result) == "table" + and not vim.tbl_isempty(result) + then + __callback(true) + return + end + if err ~= nil then lib_notify.Warn( string.format( @@ -140,125 +139,96 @@ M.request = function(buffer_id, callback) err.message ) ) - else - if - result - and type(result) == "table" - and next(result) ~= nil - then - new_callback(true) - return - end end if tmp_number == #clients then - new_callback(false) + __callback(false) end - end, buffer_id) + end + client.request(code_action_feature, params, _tmp, buffer_id) end end -local debounce_func = function(buffer_id) - local func = function() - M.request(buffer_id, function(result) - M.clear_render() - if result then - local line = fn.line(".") - if line == nil then - return - end - M.render(buffer_id, line) +local function debounce_func(buffer_id) + local _rq_cb = function(result) + M.clear_render() + if result then + local line = fn.line(".") + if line == nil then + return end - end) - end - if config.options.lightbulb.debounce then - if type(config.options.lightbulb.debounce) == "number" then - return lib_util.debounce( - func, - ---@diagnostic disable-next-line: param-type-mismatch - math.floor(config.options.lightbulb.debounce) - ) - else - return lib_util.debounce(func, 250) + M.render(buffer_id, line) end - else + end + + local func = function() + M.request(buffer_id, _rq_cb) + end + + if not config.options.lightbulb.debounce then return func + elseif config.options.lightbulb.debounce == true then + return lib_util.debounce(func, 250) end + + return lib_util.debounce( + func, + ---@diagnostic disable-next-line: param-type-mismatch + math.floor(config.options.lightbulb.debounce) + ) end -- auto command for lightbulb -M.autocmd = function() +function M.autocmd() local lightbulb_group = - api.nvim_create_augroup("Lspui_lightBulb", { clear = true }) + api.nvim_create_augroup(autogroup_name, { clear = true }) + + local function _tmp() + -- get current buffer + local current_buffer = api.nvim_get_current_buf() + local group_id = api.nvim_create_augroup( + "Lspui_lightBulb_" .. tostring(current_buffer), + { clear = true } + ) + + local new_func = debounce_func(current_buffer) + + api.nvim_create_autocmd({ "CursorHold" }, { + group = group_id, + buffer = current_buffer, + callback = vim.schedule_wrap(new_func), + desc = lib_util.command_desc("Lightbulb update when CursorHold"), + }) + + api.nvim_create_autocmd({ "InsertEnter", "WinLeave" }, { + group = group_id, + buffer = current_buffer, + callback = M.clear_render, + desc = lib_util.command_desc("Lightbulb update when InsertEnter"), + }) + + api.nvim_create_autocmd({ "BufDelete" }, { + group = group_id, + buffer = current_buffer, + callback = function() + api.nvim_del_augroup_by_id(group_id) + end, + desc = lib_util.command_desc( + "Lightbulb delete autocmd when BufDelete" + ), + }) + end -- here is just no cache option - attach_autocmd_id = api.nvim_create_autocmd("LspAttach", { + api.nvim_create_autocmd("LspAttach", { group = lightbulb_group, - callback = function() - -- get current buffer - local current_buffer = api.nvim_get_current_buf() - local group_id = api.nvim_create_augroup( - "Lspui_lightBulb_" .. tostring(current_buffer), - { clear = true } - ) - - autocmd_list[current_buffer] = {} - - local new_func = debounce_func(current_buffer) - - local hold_autocmd_id = api.nvim_create_autocmd({ "CursorHold" }, { - group = group_id, - buffer = current_buffer, - callback = vim.schedule_wrap(function() - new_func() - end), - desc = lib_util.command_desc( - "Lightbulb update when CursorHold" - ), - }) - - local move_autocmd_id = api.nvim_create_autocmd( - { "InsertEnter", "WinLeave" }, - { - group = group_id, - buffer = current_buffer, - callback = function() - M.clear_render() - end, - desc = lib_util.command_desc( - "Lightbulb update when InsertEnter" - ), - } - ) - - local wipe_autocmd_id = api.nvim_create_autocmd({ "BufWipeout" }, { - group = group_id, - buffer = current_buffer, - callback = function() - api.nvim_del_augroup_by_id(group_id) - end, - desc = lib_util.command_desc("Exec clean cmd when QuitPre"), - }) - - for _, autocmd_id in pairs({ - hold_autocmd_id, - move_autocmd_id, - wipe_autocmd_id, - }) do - table.insert(autocmd_list[current_buffer], autocmd_id) - end - end, + callback = _tmp, desc = lib_util.command_desc("Lsp attach lightbulb cmd"), }) end -M.un_autocmd = function() - pcall(api.nvim_del_autocmd, attach_autocmd_id) - for _, autocmd_ids in pairs(autocmd_list) do - for _, autocmd_id in pairs(autocmd_ids) do - pcall(api.nvim_del_autocmd, autocmd_id) - end - end +function M.un_autocmd() + api.nvim_del_augroup_by_name(autogroup_name) end return M diff --git a/lua/LspUI/signature/util.lua b/lua/LspUI/signature/util.lua index b1cbbd1..07c0d82 100644 --- a/lua/LspUI/signature/util.lua +++ b/lua/LspUI/signature/util.lua @@ -275,7 +275,9 @@ M.autocmd = function() api.nvim_create_autocmd({ "CursorMovedI", "InsertEnter" }, { group = signature_group, callback = vim.schedule_wrap(func), - desc = lib_util.command_desc("Signature update when CursorHoldI"), + desc = lib_util.command_desc( + "Signature update when CursorHoldI or InsertEnter" + ), }) -- when buffer is deleted, disable buffer siganture