-- The MIT License (MIT) -- -- Copyright © 2026 Scott E. Graves -- -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software -- and associated documentation files (the “Software”), to deal in the Software without restriction, -- including without limitation the rights to use, copy, modify, merge, publish, distribute, -- sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in all copies or -- substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -- BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- local M = {} local focus_id = "textDocument/signatureHelp" local timers = {} local config = { delay = 50, border = "rounded", max_height = 25, max_width = 120, wrap = true } local function normalize_bufnr(bufnr) if bufnr == nil or bufnr == 0 then return vim.api.nvim_get_current_buf() end return bufnr end local function cancel_timer(bufnr) local timer = timers[bufnr] timers[bufnr] = nil if timer and not timer:is_closing() then timer:stop() timer:close() end end local function close_float(bufnr) for _, win in ipairs(vim.api.nvim_list_wins()) do local ok, owner = pcall(vim.api.nvim_win_get_var, win, focus_id) if ok and owner == bufnr then pcall(vim.api.nvim_win_close, win, true) end end end function M.close(bufnr) bufnr = normalize_bufnr(bufnr) cancel_timer(bufnr) close_float(bufnr) end function M.update(bufnr) bufnr = normalize_bufnr(bufnr) if not vim.api.nvim_buf_is_valid(bufnr) or bufnr ~= vim.api.nvim_get_current_buf() then return end local clients = vim.lsp.get_clients( {bufnr = bufnr, method = "textDocument/signatureHelp"} ) if #clients == 0 then close_float(bufnr) return end vim.lsp.buf.signature_help( { anchor_bias = "above", border = config.border, focusable = false, max_height = config.max_height, max_width = config.max_width, silent = true, wrap = config.wrap } ) end function M.schedule(args) local bufnr = normalize_bufnr(args and args.buf) cancel_timer(bufnr) timers[bufnr] = vim.defer_fn( function() timers[bufnr] = nil M.update(bufnr) end, config.delay ) end function M.setup(opts) config = vim.tbl_deep_extend("force", config, opts or {}) local group = vim.api.nvim_create_augroup("DarculaLspSignature", {clear = true}) vim.api.nvim_create_autocmd( {"TextChangedI", "TextChangedP", "CursorHoldI"}, { callback = M.schedule, group = group } ) vim.api.nvim_create_autocmd( {"InsertLeave", "WinLeave"}, { callback = function(args) M.close(args.buf) end, group = group } ) vim.api.nvim_create_autocmd( "BufWipeout", { callback = function(args) cancel_timer(args.buf) end, group = group } ) end return M