Make signature and documentation seperate. Signature opens automatically and documentation
opens by calling the open documentation function which can be assigned to keys (ie. <C-S-k>)main
parent
9b4a44c441
commit
3a2a09ea38
|
|
@ -21,11 +21,14 @@ local function get_parameter_label(result)
|
|||
return ""
|
||||
end
|
||||
|
||||
if activeParameter > #signature.parameters then
|
||||
activeParameter = 0
|
||||
if activeParameter >= #signature.parameters then
|
||||
activeParameter = #signature.parameters - 1
|
||||
end
|
||||
|
||||
if signature.parameters[activeParameter + 1] == nil then
|
||||
return ""
|
||||
end
|
||||
|
||||
-- local nextParameter = signature.parameters[activeParameter + 1]
|
||||
local param = signature.parameters[activeParameter + 1].label
|
||||
local param_str
|
||||
-- Handle both string and table parameter labels
|
||||
|
|
@ -34,7 +37,7 @@ local function get_parameter_label(result)
|
|||
local e = param[2]
|
||||
param_str = string.sub(signature.label, s, e)
|
||||
elseif type(param) == "string" then
|
||||
param_str = label
|
||||
param_str = signature.label
|
||||
end
|
||||
|
||||
return param_str
|
||||
|
|
@ -86,9 +89,9 @@ local function _wrap_lines(str, maxlen, opts)
|
|||
return lines
|
||||
end
|
||||
|
||||
---@param signature_help table
|
||||
---@param maxlen integer
|
||||
local function convert_signature_help_to_lines(signature_help, maxlen)
|
||||
--@param signature_help string[]
|
||||
--@param maxlen integer
|
||||
local function make_signature_lines(signature_help, maxlen)
|
||||
if not signature_help.signatures then
|
||||
return
|
||||
end
|
||||
|
|
@ -97,6 +100,7 @@ local function convert_signature_help_to_lines(signature_help, maxlen)
|
|||
if active_signature >= #signature_help.signatures or active_signature < 0 then
|
||||
active_signature = 0
|
||||
end
|
||||
|
||||
local signature = signature_help.signatures[active_signature + 1]
|
||||
if not signature then
|
||||
return
|
||||
|
|
@ -111,27 +115,28 @@ local function convert_signature_help_to_lines(signature_help, maxlen)
|
|||
return wrapped_lines
|
||||
end
|
||||
|
||||
local function apply_treesitter_highlighting(buf, syntax)
|
||||
if not api.nvim_buf_is_valid(buf) then
|
||||
local function make_doc_lines(result, ft)
|
||||
local active_signature = result.activeSignature or 0
|
||||
local signature = result.signatures[active_signature + 1]
|
||||
local doc_lines = {}
|
||||
if not signature then
|
||||
return
|
||||
end
|
||||
|
||||
if not pcall(require, "nvim-treesitter") then
|
||||
return
|
||||
if signature.documentation then
|
||||
-- if LSP returns plain string, we treat it as plaintext. This avoids
|
||||
-- special characters like underscore or similar from being interpreted
|
||||
-- as markdown font modifiers
|
||||
if type(signature.documentation) == "string" then
|
||||
signature.documentation = { kind = "plaintext", value = signature.documentation }
|
||||
end
|
||||
|
||||
-- Store current window and buffer
|
||||
local current_win = api.nvim_get_current_win()
|
||||
local current_buf = api.nvim_get_current_buf()
|
||||
|
||||
-- Apply treesitter highlighting
|
||||
pcall(function()
|
||||
require("nvim-treesitter.highlight").attach(buf, syntax)
|
||||
end)
|
||||
|
||||
-- Restore focus
|
||||
api.nvim_set_current_win(current_win)
|
||||
api.nvim_set_current_buf(current_buf)
|
||||
vim.lsp.util.convert_input_to_markdown_lines(signature.documentation, doc_lines)
|
||||
end
|
||||
for _, parameter in ipairs(signature.parameters) do
|
||||
if parameter.documentation then
|
||||
vim.lsp.util.convert_input_to_markdown_lines(parameter.documentation, doc_lines)
|
||||
end
|
||||
end
|
||||
return doc_lines
|
||||
end
|
||||
|
||||
local _make_floating_popup_size = function(contents, opts)
|
||||
|
|
@ -147,7 +152,7 @@ local _make_floating_popup_size = function(contents, opts)
|
|||
end
|
||||
|
||||
-- local border_width = get_border_size(opts).width
|
||||
local border_width = 2 --TODO: do we need to deal with this parametrically?
|
||||
local border_width = 2 --TODO: do we need to deal with this programmatically?
|
||||
local screen_width = api.nvim_win_get_width(0)
|
||||
width = math.min(width, screen_width)
|
||||
width = math.min(width, max_width)
|
||||
|
|
@ -179,133 +184,188 @@ end
|
|||
---@param content table window content
|
||||
---@param opts table window options
|
||||
---@returns (table) Options
|
||||
local function _make_floating_popup_options(content, opts)
|
||||
local width, height = _make_floating_popup_size(content, opts)
|
||||
local function _make_floating_popup_options(sig_content, doc_content, opts)
|
||||
local sig_width, sig_height = _make_floating_popup_size(sig_content, opts)
|
||||
local doc_width, doc_height = _make_floating_popup_size(doc_content, opts)
|
||||
local border_height = 2 --TODO: get this from opts
|
||||
|
||||
local offset_y = opts.offset_y or 0
|
||||
local offset_x = opts.offset_x or 0
|
||||
|
||||
local anchor_bias = opts.anchor_bias or "auto"
|
||||
local relative = opts.relative or "cursor"
|
||||
local anchor = ""
|
||||
local row, col
|
||||
local relative = "win"
|
||||
local sig_anchor
|
||||
local doc_anchor
|
||||
local sig_row, sig_col
|
||||
local doc_row, doc_col
|
||||
local curs_row = vim.fn.winline()
|
||||
local curs_col = vim.fn.wincol()
|
||||
|
||||
local lines_above = opts.relative == "mouse" and vim.fn.getmousepos().line - 1 or vim.fn.winline() - 1
|
||||
local lines_above = curs_row - 1
|
||||
local lines_below = vim.fn.winheight(0) - lines_above
|
||||
|
||||
if
|
||||
lines_above < height
|
||||
or (anchor_bias == "below" and lines_below > height + offset_y)
|
||||
if -- figure out signature anchor and height
|
||||
lines_above < sig_height + border_height
|
||||
or (anchor_bias == "below" and lines_below > sig_height + border_height + offset_y)
|
||||
or (anchor_bias == "auto" and lines_below > lines_above)
|
||||
then
|
||||
anchor = anchor .. "N"
|
||||
height = math.min(lines_below - offset_y, height)
|
||||
row = 1 + offset_y
|
||||
sig_anchor = "N"
|
||||
sig_height = math.min(lines_below - offset_y, sig_height)
|
||||
sig_row = curs_row + offset_y
|
||||
else
|
||||
anchor = anchor .. "S"
|
||||
height = math.min(lines_above - offset_y, height)
|
||||
row = 0 - offset_y
|
||||
sig_anchor = "S"
|
||||
sig_height = math.min(lines_above - offset_y, sig_height)
|
||||
sig_row = curs_row - 1 - offset_y
|
||||
end
|
||||
|
||||
local wincol = opts.relative == "mouse" and vim.fn.getmousepos().column or vim.fn.wincol()
|
||||
|
||||
if wincol + width + offset_x <= vim.o.columns then
|
||||
anchor = anchor .. "W"
|
||||
col = 0 - wincol
|
||||
if sig_anchor == "N" then
|
||||
lines_below = lines_below - (sig_height + border_height) --new lines_below including sig
|
||||
else
|
||||
anchor = anchor .. "E"
|
||||
col = 1 - wincol
|
||||
lines_above = lines_above - (sig_height + border_height) --new lines_above including sig
|
||||
end
|
||||
|
||||
offset_x = opts.offset_x or 0
|
||||
if -- figure out documentation anchor and height
|
||||
lines_above < doc_height + border_height
|
||||
or (anchor_bias == "below" and lines_below > doc_height + border_height)
|
||||
or (anchor_bias == "auto" and lines_below > lines_above)
|
||||
then
|
||||
doc_anchor = "N"
|
||||
doc_height = math.min(lines_below, doc_height)
|
||||
if sig_anchor == "N" then --docs and sigs below
|
||||
doc_row = curs_row + offset_y + (sig_height + border_height) - 1
|
||||
else --docs above sigs below
|
||||
doc_row = curs_row - 1 - offset_y
|
||||
end
|
||||
else
|
||||
doc_anchor = "S"
|
||||
doc_height = math.min(lines_above, doc_height)
|
||||
if sig_anchor == "S" then --docs and sigs above
|
||||
doc_row = curs_row - (offset_y + sig_height + border_height)
|
||||
else --docs below sigs above
|
||||
doc_row = curs_row - 1 - offset_y
|
||||
end
|
||||
end
|
||||
|
||||
local wincol = vim.fn.wincol()
|
||||
if wincol + sig_width + offset_x <= vim.o.columns then
|
||||
sig_anchor = sig_anchor .. "W"
|
||||
doc_anchor = doc_anchor .. "W"
|
||||
sig_col = curs_col - wincol
|
||||
doc_col = curs_col - wincol
|
||||
else
|
||||
sig_anchor = sig_anchor .. "E"
|
||||
doc_anchor = doc_anchor .. "E"
|
||||
sig_col = curs_col + 1 - wincol
|
||||
doc_col = curs_col + 1 - wincol
|
||||
end
|
||||
local first_col = vim.fn.getwininfo(vim.fn.win_getid())[1].textoff
|
||||
|
||||
return {
|
||||
anchor = anchor,
|
||||
row = row,
|
||||
col = col + first_col + offset_x,
|
||||
width = width,
|
||||
height = height,
|
||||
return { --signature window options
|
||||
anchor = sig_anchor,
|
||||
row = sig_row,
|
||||
col = sig_col + first_col + offset_x,
|
||||
width = sig_width,
|
||||
height = sig_height,
|
||||
focusable = opts.focusable,
|
||||
relative = relative,
|
||||
style = "minimal",
|
||||
border = opts.border or "rounded",
|
||||
zindex = opts.zindex or 50,
|
||||
-- winblend = opts.winblend or 10,
|
||||
}, { --documentation window options
|
||||
anchor = doc_anchor,
|
||||
row = doc_row,
|
||||
col = doc_col + first_col + offset_x,
|
||||
width = doc_width,
|
||||
height = doc_height,
|
||||
focusable = opts.focusable,
|
||||
relative = relative,
|
||||
style = "minimal",
|
||||
border = opts.border or "rounded",
|
||||
zindex = opts.zindex or 50,
|
||||
-- winblend = opts.winblend or 10,
|
||||
}
|
||||
end
|
||||
|
||||
local function create_float_window(content, syntax, opts)
|
||||
---@param result string[] signature help result
|
||||
---@param syntax string syntax language for highlighting. i.e. "lua" or "markdown"
|
||||
---@param opts table window options
|
||||
---@return function function to open signature window
|
||||
---@return function function to open documentation window
|
||||
local function create_float_windows(result, syntax, opts)
|
||||
local npcall = vim.F.npcall
|
||||
vim.validate({
|
||||
contents = { content, "t" },
|
||||
result = { result, "t" },
|
||||
syntax = { syntax, "s", true },
|
||||
opts = { opts, "t", true },
|
||||
})
|
||||
opts = opts or {}
|
||||
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local existing_float = npcall(api.nvim_buf_get_var, bufnr, "lsp_floating_preview")
|
||||
local existing_sig_win = npcall(api.nvim_buf_get_var, bufnr, "lsp_sig_win")
|
||||
local existing_doc_win = npcall(api.nvim_buf_get_var, bufnr, "lsp_doc_win")
|
||||
|
||||
if existing_float and api.nvim_win_is_valid(existing_float) then
|
||||
api.nvim_win_close(existing_float, true)
|
||||
if existing_sig_win and api.nvim_win_is_valid(existing_sig_win) then
|
||||
api.nvim_win_close(existing_sig_win, true)
|
||||
end
|
||||
if existing_doc_win and api.nvim_win_is_valid(existing_doc_win) then
|
||||
api.nvim_win_close(existing_doc_win, true)
|
||||
end
|
||||
|
||||
-- Create the buffer
|
||||
local floating_bufnr = api.nvim_create_buf(false, true)
|
||||
-- Create the buffers
|
||||
local sig_bufnr = api.nvim_create_buf(false, true)
|
||||
local doc_bufnr = api.nvim_create_buf(false, true)
|
||||
|
||||
if syntax then
|
||||
vim.bo[floating_bufnr].syntax = syntax
|
||||
vim.bo[floating_bufnr].ft = syntax
|
||||
vim.treesitter.start(floating_bufnr)
|
||||
end
|
||||
api.nvim_buf_set_lines(floating_bufnr, 0, -1, true, content)
|
||||
syntax = syntax or "text"
|
||||
vim.bo[sig_bufnr].syntax = syntax
|
||||
vim.bo[sig_bufnr].ft = syntax
|
||||
vim.treesitter.start(sig_bufnr)
|
||||
vim.bo[doc_bufnr].syntax = "markdown"
|
||||
vim.bo[doc_bufnr].ft = "markdown"
|
||||
vim.treesitter.start(doc_bufnr)
|
||||
|
||||
local float_options = _make_floating_popup_options(content, opts)
|
||||
local floating_winnr = api.nvim_open_win(floating_bufnr, false, float_options)
|
||||
local sig_content = make_signature_lines(result, opts.max_width)
|
||||
local doc_content = make_doc_lines(result, syntax)
|
||||
api.nvim_buf_set_lines(sig_bufnr, 0, -1, true, sig_content)
|
||||
api.nvim_buf_set_lines(doc_bufnr, 0, -1, true, doc_content)
|
||||
|
||||
vim.wo[floating_winnr].conceallevel = 2
|
||||
vim.wo[floating_winnr].foldenable = false
|
||||
vim.bo[floating_bufnr].modifiable = false
|
||||
vim.bo[floating_bufnr].bufhidden = "wipe"
|
||||
|
||||
api.nvim_buf_set_keymap(
|
||||
floating_bufnr,
|
||||
"n",
|
||||
"q",
|
||||
"<cmd>bdelete<cr>",
|
||||
{ silent = true, noremap = true, nowait = true }
|
||||
)
|
||||
local sig_float_options, doc_float_options = _make_floating_popup_options(sig_content, doc_content, opts)
|
||||
return function()
|
||||
local sig_winnr = api.nvim_open_win(sig_bufnr, false, sig_float_options)
|
||||
vim.wo[sig_winnr].conceallevel = 2
|
||||
vim.wo[sig_winnr].foldenable = false
|
||||
vim.bo[sig_bufnr].modifiable = false
|
||||
vim.bo[sig_bufnr].bufhidden = "hide"
|
||||
-- save focus_id
|
||||
api.nvim_buf_set_var(bufnr, "lsp_sig_win", sig_winnr)
|
||||
return sig_bufnr, sig_winnr, sig_content
|
||||
end, function()
|
||||
local doc_winnr = api.nvim_open_win(doc_bufnr, false, doc_float_options)
|
||||
vim.wo[doc_winnr].conceallevel = 2
|
||||
vim.wo[doc_winnr].foldenable = false
|
||||
vim.bo[doc_bufnr].modifiable = false
|
||||
vim.bo[doc_bufnr].bufhidden = "hide"
|
||||
|
||||
-- save focus_id
|
||||
api.nvim_buf_set_var(bufnr, "lsp_floating_preview", floating_winnr)
|
||||
|
||||
return floating_bufnr, floating_winnr
|
||||
api.nvim_buf_set_var(doc_bufnr, "lsp_doc_win", doc_winnr)
|
||||
return doc_bufnr, doc_winnr
|
||||
end
|
||||
end
|
||||
|
||||
local function close_float_window(win, buf)
|
||||
-- Store current window and buffer
|
||||
local current_win = api.nvim_get_current_win()
|
||||
local current_buf = api.nvim_get_current_buf()
|
||||
|
||||
if win and api.nvim_win_is_valid(win) then
|
||||
pcall(api.nvim_win_close, win, true)
|
||||
local function close_float_window(winnr)
|
||||
if winnr and api.nvim_win_is_valid(winnr) then
|
||||
pcall(api.nvim_win_close, winnr, true)
|
||||
end
|
||||
if buf and api.nvim_buf_is_valid(buf) then
|
||||
pcall(api.nvim_buf_delete, buf, { force = true })
|
||||
end
|
||||
win = nil
|
||||
buf = nil
|
||||
|
||||
-- Restore focus
|
||||
pcall(api.nvim_set_current_win, current_win)
|
||||
pcall(api.nvim_set_current_buf, current_buf)
|
||||
-- end
|
||||
local function delete_buffer(bufnr)
|
||||
if bufnr and api.nvim_buf_is_valid(bufnr) then
|
||||
pcall(api.nvim_buf_delete, bufnr, { force = true })
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
get_parameter_label = get_parameter_label,
|
||||
convert_signature_help_to_lines = convert_signature_help_to_lines,
|
||||
apply_treesitter_highlighting = apply_treesitter_highlighting,
|
||||
create_float_window = create_float_window,
|
||||
create_float_windows = create_float_windows,
|
||||
close_float_window = close_float_window,
|
||||
delete_buffer = delete_buffer,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ SignatureHelp.__index = SignatureHelp
|
|||
|
||||
function SignatureHelp.new()
|
||||
local instance = setmetatable({
|
||||
sig_win = nil,
|
||||
sig_buf = nil,
|
||||
doc_win = nil,
|
||||
doc_buf = nil,
|
||||
showing = false,
|
||||
_display_sig_win = function() end, -- function to open signatures window
|
||||
_display_doc_win = function() end, -- function to open documentation window
|
||||
sig_content = nil, -- current signature buffer content
|
||||
sig_winnr = nil,
|
||||
sig_bufnr = nil,
|
||||
sig_win_height = nil,
|
||||
sig_win_showing = false,
|
||||
ns = nil,
|
||||
markid = nil,
|
||||
timer = nil,
|
||||
|
|
@ -20,6 +22,11 @@ function SignatureHelp.new()
|
|||
enabled = false,
|
||||
normal_mode_active = false,
|
||||
current_signature_idx = nil,
|
||||
|
||||
doc_winnr = nil,
|
||||
doc_bufnr = nil,
|
||||
doc_win_showing = false,
|
||||
doc_win_focused = false,
|
||||
config = nil,
|
||||
}, SignatureHelp)
|
||||
|
||||
|
|
@ -47,7 +54,7 @@ function SignatureHelp.new()
|
|||
winblend = 10,
|
||||
zindex = 200,
|
||||
focusable = false,
|
||||
max_height = 10,
|
||||
max_height = 20,
|
||||
max_width = 80,
|
||||
anchor_bias = "below", -- below|above|auto
|
||||
relative = "cursor",
|
||||
|
|
@ -59,7 +66,6 @@ function SignatureHelp.new()
|
|||
auto_close = true,
|
||||
preview_parameters = true,
|
||||
debounce_time = 100,
|
||||
toggle_key = "<C-k>",
|
||||
render_style = {
|
||||
separator = true,
|
||||
compact = true,
|
||||
|
|
@ -70,122 +76,28 @@ function SignatureHelp.new()
|
|||
return instance
|
||||
end
|
||||
|
||||
-- local function signature_index_comment(index)
|
||||
-- if #vim.bo.commentstring ~= 0 then
|
||||
-- return vim.bo.commentstring:format(index)
|
||||
-- else
|
||||
-- return "(" .. index .. ")"
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- local function markdown_for_signature_list(signatures, config)
|
||||
-- local lines, labels = {}, {}
|
||||
-- local number = config.number and #signatures > 1
|
||||
-- local max_method_len = 0
|
||||
--
|
||||
-- -- First pass to calculate alignment
|
||||
-- if config.render_style.align_icons then
|
||||
-- for _, signature in ipairs(signatures) do
|
||||
-- max_method_len = math.max(max_method_len, #signature.label)
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- for index, signature in ipairs(signatures) do
|
||||
-- if not config.render_style.compact then
|
||||
-- table.insert(lines, "")
|
||||
-- end
|
||||
-- table.insert(labels, #lines + 1)
|
||||
--
|
||||
-- local suffix = number and (" " .. signature_index_comment(index)) or ""
|
||||
-- local padding = config.render_style.align_icons and string.rep(" ", max_method_len - #signature.label) or " "
|
||||
--
|
||||
-- -- Method signature with syntax highlighting
|
||||
-- table.insert(lines, string.format("```%s", vim.bo.filetype))
|
||||
-- -- table.insert(lines, string.format("%s Method:", config.icons.method))
|
||||
-- table.insert(lines, string.format("%s %s%s%s", config.icons.method, signature.label, padding, suffix))
|
||||
-- table.insert(lines, "```")
|
||||
--
|
||||
-- -- -- Parameters section
|
||||
-- -- if signature.parameters and #signature.parameters > 0 then
|
||||
-- -- if config.render_style.separator then
|
||||
-- -- table.insert(lines, string.rep("─", 40))
|
||||
-- -- end
|
||||
-- -- table.insert(lines, string.format("%s Parameters:", config.icons.parameter))
|
||||
-- -- for _, param in ipairs(signature.parameters) do
|
||||
-- -- local param_doc = param.documentation and string.format(" - %s", vim.inspect(param.documentation))
|
||||
-- -- table.insert(lines, string.format(" • %s = %s", vim.inspect(param.label), param_doc))
|
||||
-- -- end
|
||||
-- -- end
|
||||
--
|
||||
-- -- Documentation section
|
||||
-- if signature.documentation then
|
||||
-- if config.render_style.separator then
|
||||
-- table.insert(lines, string.rep("─", 40))
|
||||
-- end
|
||||
-- table.insert(lines, string.format("%s Documentation:", config.icons.documentation))
|
||||
-- local doc_lines = vim.split(signature.documentation.value or signature.documentation, "\n")
|
||||
-- for _, line in ipairs(doc_lines) do
|
||||
-- table.insert(lines, " " .. line)
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- if index ~= #signatures and config.render_style.separator then
|
||||
-- table.insert(lines, string.rep("═", 40))
|
||||
-- end
|
||||
-- end
|
||||
-- return lines, labels
|
||||
-- end
|
||||
--
|
||||
-- function SignatureHelp:create_float_window(contents)
|
||||
-- local max_width = math.min(self.config.max_width, vim.o.columns)
|
||||
-- local max_height = math.min(self.config.max_height, #contents)
|
||||
--
|
||||
-- -- Calculate optimal position
|
||||
-- local cursor = api.nvim_win_get_cursor(0)
|
||||
-- local cursor_line = cursor[1]
|
||||
-- local screen_line = vim.fn.screenpos(0, cursor_line, 1).row
|
||||
--
|
||||
-- local row_offset = self.config.floating_window_above_cur_line and -max_height - 1 or 1
|
||||
-- if screen_line + row_offset < 1 then
|
||||
-- row_offset = 2 -- Show below if not enough space above
|
||||
-- end
|
||||
--
|
||||
-- local win_config = {
|
||||
-- relative = "cursor",
|
||||
-- row = row_offset - 1,
|
||||
-- col = 0,
|
||||
-- width = max_width,
|
||||
-- height = max_height,
|
||||
-- style = "minimal",
|
||||
-- border = self.config.border,
|
||||
-- zindex = 50, -- Ensure it's above most other floating windows
|
||||
-- }
|
||||
--
|
||||
-- if self.win and api.nvim_win_is_valid(self.win) then
|
||||
-- api.nvim_win_set_config(self.win, win_config)
|
||||
-- api.nvim_win_set_buf(self.win, self.buf)
|
||||
-- else
|
||||
-- self.buf = api.nvim_create_buf(false, true)
|
||||
-- self.win = api.nvim_open_win(self.buf, false, win_config)
|
||||
-- end
|
||||
--
|
||||
-- vim.bo[self.buf].modifiable = true
|
||||
-- api.nvim_buf_set_lines(self.buf, 0, -1, false, contents)
|
||||
-- vim.bo[self.buf].modifiable = false
|
||||
-- vim.wo[self.win][self.buf].foldenable = false
|
||||
-- vim.wo[self.win][self.buf].wrap = true
|
||||
-- vim.wo[self.win][self.buf].winblend = self.config.winblend
|
||||
-- self.visible = true
|
||||
-- end
|
||||
--
|
||||
function SignatureHelp:hide_sig_win()
|
||||
helper.close_float_window(self.sig_win, self.sig_buf)
|
||||
if self.sig_win_showing then
|
||||
helper.close_float_window(self.sig_winnr)
|
||||
end
|
||||
helper.delete_buffer(self.sig_bufnr)
|
||||
helper.delete_buffer(self.doc_bufnr)
|
||||
|
||||
self:hide_doc_win()
|
||||
|
||||
self.sig_winnr = nil
|
||||
self.sig_bufnr = nil
|
||||
self.doc_bufnr = nil -- we want to nil this here and not when we hide the doc win in case we want to reopen the doc win
|
||||
self.current_signatures = nil
|
||||
self.showing = false
|
||||
self.sig_win_showing = false
|
||||
end
|
||||
|
||||
function SignatureHelp:hide_doc_win()
|
||||
helper.close_float_window(self.doc_win, self.doc_buf)
|
||||
if self.doc_win_showing then
|
||||
helper.close_float_window(self.doc_winnr)
|
||||
self.doc_winnr = nil
|
||||
self.doc_win_showing = false
|
||||
end
|
||||
end
|
||||
|
||||
function SignatureHelp:extract_default_value(param_info)
|
||||
|
|
@ -215,7 +127,7 @@ function SignatureHelp:extract_default_value(param_info)
|
|||
end
|
||||
|
||||
function SignatureHelp:set_active_parameter_highlights(param_str, lines)
|
||||
if not self.sig_buf or not api.nvim_buf_is_valid(self.sig_buf) then
|
||||
if not self.sig_bufnr or not api.nvim_buf_is_valid(self.sig_bufnr) then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -234,7 +146,7 @@ function SignatureHelp:set_active_parameter_highlights(param_str, lines)
|
|||
|
||||
if s and e and s > 0 then
|
||||
self.markid = api.nvim_buf_set_extmark(
|
||||
self.sig_buf,
|
||||
self.sig_bufnr,
|
||||
self.ns,
|
||||
line_num,
|
||||
s,
|
||||
|
|
@ -243,21 +155,59 @@ function SignatureHelp:set_active_parameter_highlights(param_str, lines)
|
|||
end
|
||||
end
|
||||
|
||||
function SignatureHelp:display(result)
|
||||
function SignatureHelp:display_sig_win(result)
|
||||
if not result or not result.signatures or #result.signatures == 0 then
|
||||
self:hide_sig_win()
|
||||
if self.doc_win_showing then
|
||||
self:hide_doc_win()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local content = helper.convert_signature_help_to_lines(result, self.config.win_opts.max_width)
|
||||
if not self.showing then
|
||||
self.sig_buf, self.sig_win = helper.create_float_window(content, "lua", self.config.win_opts) -- TODO: programmatically set file type:
|
||||
if not self.sig_win_showing then
|
||||
local ft = vim.bo.ft
|
||||
self._display_sig_win, self._display_doc_win = helper.create_float_windows(result, ft, self.config.win_opts)
|
||||
self.sig_bufnr, self.sig_winnr, self.sig_content = self._display_sig_win()
|
||||
|
||||
local param_str = helper.get_parameter_label(result)
|
||||
self:set_active_parameter_highlights(param_str, content)
|
||||
self.showing = true
|
||||
self:set_active_parameter_highlights(param_str, self.sig_content)
|
||||
self.sig_win_showing = true
|
||||
end
|
||||
local param_str = helper.get_parameter_label(result)
|
||||
self:set_active_parameter_highlights(param_str, content)
|
||||
self:set_active_parameter_highlights(param_str, self.sig_content)
|
||||
end
|
||||
|
||||
function SignatureHelp:display_doc_win()
|
||||
if self.doc_win_showing then
|
||||
return
|
||||
else
|
||||
self.doc_bufnr, self.doc_winnr = self._display_doc_win()
|
||||
self.doc_win_showing = true
|
||||
self.doc_win_focused = true
|
||||
local active_winnr = vim.api.nvim_get_current_win()
|
||||
vim.api.nvim_set_current_win(self.doc_winnr)
|
||||
|
||||
exit_docs = function()
|
||||
vim.api.nvim_set_current_win(active_winnr)
|
||||
vim.fn.feedkeys("i", "t") --put us back into insert mode
|
||||
self.doc_win_focused = false
|
||||
end
|
||||
|
||||
if self.doc_bufnr ~= nil then
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"q",
|
||||
exit_docs,
|
||||
{ silent = true, noremap = true, nowait = true, buffer = self.doc_bufnr }
|
||||
)
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"<esc>",
|
||||
exit_docs,
|
||||
{ silent = true, noremap = true, nowait = true, buffer = self.doc_bufnr }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SignatureHelp:trigger()
|
||||
|
|
@ -272,14 +222,17 @@ function SignatureHelp:trigger()
|
|||
vim.notify("Error in LSP Signature Help: " .. vim.inspect(err), vim.log.levels.ERROR)
|
||||
end
|
||||
self:hide_sig_win()
|
||||
self:hide_doc_win()
|
||||
return
|
||||
end
|
||||
|
||||
if result and result.signatures and #result.signatures > 0 then
|
||||
self.current_signatures = result.signatures
|
||||
self:display(result)
|
||||
|
||||
self:display_sig_win(result)
|
||||
else
|
||||
self:hide_sig_win()
|
||||
self:hide_doc_win()
|
||||
-- Only notify if not silent and if there was actually no signature help
|
||||
if not self.config.silent and result then
|
||||
vim.notify("No signature help available", vim.log.levels.INFO)
|
||||
|
|
@ -299,22 +252,10 @@ function SignatureHelp:check_capability()
|
|||
self.enabled = false
|
||||
end
|
||||
|
||||
function SignatureHelp:toggle_normal_mode()
|
||||
self.normal_mode_active = not self.normal_mode_active
|
||||
if self.normal_mode_active then
|
||||
self:trigger()
|
||||
else
|
||||
self:hide_sig_win()
|
||||
end
|
||||
end
|
||||
|
||||
function SignatureHelp:setup_autocmds()
|
||||
local group = api.nvim_create_augroup("LspSignatureHelp", { clear = true })
|
||||
|
||||
local function debounced_trigger()
|
||||
-- vim.defer_fn(function()
|
||||
-- self:trigger()
|
||||
-- end, 30)
|
||||
if self.timer then
|
||||
vim.fn.timer_stop(self.timer)
|
||||
end
|
||||
|
|
@ -326,8 +267,6 @@ function SignatureHelp:setup_autocmds()
|
|||
api.nvim_create_autocmd({ "InsertEnter", "CursorMovedI" }, {
|
||||
group = group,
|
||||
callback = function()
|
||||
-- vim.notify("trigger")
|
||||
|
||||
-- local cmp_visible = require("cmp").visible()
|
||||
-- if cmp_visible then
|
||||
-- self:hide()
|
||||
|
|
@ -351,8 +290,11 @@ function SignatureHelp:setup_autocmds()
|
|||
api.nvim_create_autocmd({ "InsertLeave" }, {
|
||||
group = group,
|
||||
callback = function()
|
||||
if self.doc_win_focused == false then
|
||||
self:hide_sig_win()
|
||||
self:hide_doc_win()
|
||||
self.normal_mode_active = false
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
|
@ -375,7 +317,7 @@ function SignatureHelp:next_signature()
|
|||
if self.current_signature_idx > #self.current_signatures then
|
||||
self.current_signature_idx = 1
|
||||
end
|
||||
self:display({
|
||||
self:display_sig_win({
|
||||
signatures = self.current_signatures,
|
||||
activeParameter = self.current_active_parameter,
|
||||
activeSignature = self.current_signature_idx - 1,
|
||||
|
|
@ -390,21 +332,28 @@ function SignatureHelp:prev_signature()
|
|||
if self.current_signature_idx < 1 then
|
||||
self.current_signature_idx = #self.current_signatures
|
||||
end
|
||||
self:display({
|
||||
self:display_sig_win({
|
||||
signatures = self.current_signatures,
|
||||
activeParameter = self.current_active_parameter,
|
||||
activeSignature = self.current_signature_idx - 1,
|
||||
})
|
||||
end
|
||||
|
||||
function SignatureHelp:setup_keymaps()
|
||||
-- Setup toggle keys using the actual config
|
||||
local toggle_key = self.config.toggle_key
|
||||
function SignatureHelp:toggle_docs()
|
||||
-- vim.notify("doc_win_showing: " .. vim.inspect(self.doc_win_showing))
|
||||
if self.doc_win_showing then
|
||||
self:hide_doc_win()
|
||||
elseif self.sig_win_showing then
|
||||
self:display_doc_win()
|
||||
end
|
||||
end
|
||||
|
||||
if toggle_key then
|
||||
vim.keymap.set("n", toggle_key, function()
|
||||
self:toggle_normal_mode()
|
||||
end, { noremap = true, silent = true, desc = "Toggle signature help in normal mode" })
|
||||
function SignatureHelp:toggle_normal_mode()
|
||||
self.normal_mode_active = not self.normal_mode_active
|
||||
if self.normal_mode_active then
|
||||
self:trigger()
|
||||
else
|
||||
self:hide_sig_win()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -447,14 +396,22 @@ function M.setup(opts)
|
|||
callback = setup_highlights,
|
||||
})
|
||||
|
||||
-- Setup autocmds and keymaps
|
||||
-- Setup autocmds
|
||||
signature_help:setup_autocmds()
|
||||
signature_help:setup_keymaps()
|
||||
|
||||
-- Store instance for potential reuse
|
||||
M._initialized = true
|
||||
M._instance = signature_help
|
||||
|
||||
-- Add API methods for external use
|
||||
M.toggle_docs = function()
|
||||
signature_help:toggle_docs()
|
||||
end
|
||||
|
||||
M.toggle_normal_mode = function()
|
||||
signature_help:toggle_normal_mode()
|
||||
end
|
||||
|
||||
return signature_help
|
||||
end
|
||||
|
||||
|
|
@ -464,6 +421,4 @@ M.dependencies = {
|
|||
"nvim-treesitter/nvim-treesitter",
|
||||
}
|
||||
|
||||
-- Add API methods for external use
|
||||
|
||||
return M
|
||||
|
|
|
|||
Loading…
Reference in New Issue