Files
darcula_nvim/nvim/lua/darcula/lsp/signature.lua
T
2026-08-29 18:49:08 -05:00

138 lines
3.4 KiB
Lua

-- The MIT License (MIT)
--
-- Copyright © 2026 Scott E. Graves <scott.e.graves@protonmail.com>
--
-- 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