Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,11 @@ e.g.
close_timeout = 4000, -- close floating window after ms when laster parameter is entered
fix_pos = false, -- set to true, the floating window will not auto-close until finish all parameters
hint_enable = true, -- virtual hint enable
disable_lsp_inlay = false, -- disable lsp inlay hints that can cover the signature help
hint_prefix = "🐼 ", -- Panda for parameter, NOTE: for the terminal not support emoji, might crash
-- or, provide a table with 3 icons
-- or, provide a table with 4 icons
-- hint_prefix = {
-- default = "🐼 ", -- if above/current/below is not specified
-- above = "↙ ", -- when the hint is on the line above the current line
-- current = "← ", -- when the hint is on the same line
-- below = "↖ " -- when the hint is on the line below the current line
Expand Down
34 changes: 34 additions & 0 deletions lua/lsp_signature/helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ local function is_special(ch)
return contains(special_chars, ch)
end

-- get inlay lsp hints of current line
local function inlay_hints()
local lsp_inlay = vim.api.nvim_create_namespace('vim_lsp_inlayhint')
local r = vim.api.nvim_win_get_cursor(0)
local start, _end = { r[1] - 1, 0 }, { r[1] - 1, r[2] }
local mk = vim.api.nvim_buf_get_extmarks(0, lsp_inlay, start, _end, { details = true })
return mk
end

local function fs_write(path, data)
local uv = vim.uv or vim.loop

Expand Down Expand Up @@ -547,6 +556,31 @@ local make_floating_popup_size = function(contents, opts)
return width, height
end

helper.inline_string_width = function()
local width = fn.strdisplaywidth
local w = 0
-- if inlay hint enabled
if vim.lsp.inlay_hint and vim.lsp.inlay_hint.is_enabled({ bufnr = 0 }) then
local hints = inlay_hints()
if hints == nil then
return w
end
-- virt_text = { { "x:", "LspInlayHint" }, { " " } },
for _, value in pairs(hints) do
-- helper.log(value)
local v = value[4] and value[4].virt_text or nil
if v == nil then
helper.log('no virt_text', value)
return w
end
for _, v2 in pairs(v) do
w = w + width(v2[1])
end
end
end
return w
end

helper.cal_pos = function(contents, opts)
local lnum = fn.line('.') - fn.line('w0') + 1

Expand Down
75 changes: 41 additions & 34 deletions lua/lsp_signature/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ _LSP_SIG_CFG = {
end,
-- also can be bool value fix floating_window position
hint_enable = true, -- virtual hint
hint_prefix = '🐼 ',
disable_lsp_inlay = false,
hint_prefix = {
default = '🐼 ', -- Panda for parameter
-- above = "↙ ", -- when the hint is on the line above the current line
-- current = "← ", -- when the hint is on the same line
-- below = "↖ " -- when the hint is on the line below the current line
},
hint_scheme = 'String',
hint_inline = function()
-- options:
Expand Down Expand Up @@ -115,35 +121,38 @@ local function virtual_hint(hint, off_y)
end
local pl
local completion_visible = helper.completion_visible()
local hp = type(_LSP_SIG_CFG.hint_prefix) == 'string' and _LSP_SIG_CFG.hint_prefix
or (type(_LSP_SIG_CFG.hint_prefix) == 'table' and _LSP_SIG_CFG.hint_prefix.current)
or '🐼 '
-- local hp = type(_LSP_SIG_CFG.hint_prefix) == 'string' and _LSP_SIG_CFG.hint_prefix
-- or (type(_LSP_SIG_CFG.hint_prefix) == 'table' and _LSP_SIG_CFG.hint_prefix.current)
-- or '🐼 '
local gethp = function(pos)
if type(_LSP_SIG_CFG.hint_prefix) == 'string' then
-- this should not happen
vim.notify('hint_prefix should be a table, please report an issue', vim.log.levels.ERROR)
return _LSP_SIG_CFG.hint_prefix
end
return _LSP_SIG_CFG.hint_prefix[pos] or _LSP_SIG_CFG.hint_prefix.default or '🐼 '
end

local hp = gethp('default')
if off_y and off_y ~= 0 then
local inline = type(_LSP_SIG_CFG.hint_inline) == 'function'
and _LSP_SIG_CFG.hint_inline() == 'inline'
or _LSP_SIG_CFG.hint_inline
-- stay out of the way of the pum
if completion_visible or inline then
show_at = cur_line
if type(_LSP_SIG_CFG.hint_prefix) == 'table' then
hp = _LSP_SIG_CFG.hint_prefix.current or '🐼 '
end
hp = gethp('current')
else
-- if no pum, show at user configured line
if off_y > 0 then
-- line below
show_at = cur_line + 1
if type(_LSP_SIG_CFG.hint_prefix) == 'table' then
hp = _LSP_SIG_CFG.hint_prefix.below or '🐼 '
end
hp = gethp('below')
end
if off_y < 0 then
-- line above
show_at = cur_line - 1
if type(_LSP_SIG_CFG.hint_prefix) == 'table' then
hp = _LSP_SIG_CFG.hint_prefix.above or '🐼 '
end
hp = gethp('above')
end
end
end
Expand All @@ -157,20 +166,13 @@ local function virtual_hint(hint, off_y)
if prev_line and vim.fn.strdisplaywidth(prev_line) < r[2] then
show_at = cur_line - 1
pl = prev_line
if type(_LSP_SIG_CFG.hint_prefix) == 'table' then
hp = _LSP_SIG_CFG.hint_prefix.above or '🐼 '
end
hp = gethp('above')
elseif next_line and dwidth(next_line) < r[2] + 2 and not completion_visible then
show_at = cur_line + 1
pl = next_line
if type(_LSP_SIG_CFG.hint_prefix) == 'table' then
hp = _LSP_SIG_CFG.hint_prefix.below or '🐼 '
end
hp = gethp('below')
else
show_at = cur_line
if type(_LSP_SIG_CFG.hint_prefix) == 'table' then
hp = _LSP_SIG_CFG.hint_prefix.current or '🐼 '
end
hp = gethp('current')
end

log('virtual text only :', prev_line, next_line, r, show_at, pl)
Expand All @@ -183,8 +185,11 @@ local function virtual_hint(hint, off_y)
if inline_display == false then
local line_to_cursor_width = dwidth(line_to_cursor)
local pl_width = dwidth(pl)
-- log(pl, pl_width, line_to_cursor_width, r[2])
if show_at ~= cur_line and line_to_cursor_width > pl_width + 1 then
pad = string.rep(' ', line_to_cursor_width - pl_width)
local off = line_to_cursor_width - pl_width
off = off + helper.inline_string_width()
pad = string.rep(' ', off)
local width = vim.api.nvim_win_get_width(0)
local hint_width = dwidth(hp .. hint)
-- todo: 6 is width of sign+linenumber column
Expand Down Expand Up @@ -230,17 +235,15 @@ local function virtual_hint(hint, off_y)
r[1] - 1,
offset,
{ -- Note: the vt was put after of cursor.
-- this seems eaiser to handle in the code also easy to read
-- easier to handle in the code also easy to read
virt_text_pos = inline_display,
-- virt_text_pos = 'right_align',
virt_text = { vt },
hl_mode = 'combine',
ephemeral = false,
-- hl_group = _LSP_SIG_CFG.hint_scheme
}
)
else -- I may deprecated this when nvim 0.10 release
log('virtual text: ', cur_line, show_at, vt)
vim.api.nvim_buf_set_extmark(0, _LSP_SIG_VT_NS, show_at, 0, {
virt_text = { vt },
virt_text_pos = 'eol',
Expand All @@ -255,7 +258,6 @@ local close_events = { 'InsertLeave', 'BufHidden', 'ModeChanged' }
-- ----------------------
-- -- signature help --
-- ----------------------
-- Note: 0.6.x - signature_help(err, {result}, {ctx}, {config})
local signature_handler = function(err, result, ctx, config)
if err ~= nil then
print('lsp_signatur handler', err)
Expand Down Expand Up @@ -985,12 +987,6 @@ M.on_attach = function(cfg, bufnr)
end
-- stylua ignore end

if type(cfg) == 'table' then
_LSP_SIG_CFG = vim.tbl_extend('keep', cfg, _LSP_SIG_CFG)
cleanup_logs(cfg)
-- log(_LSP_SIG_CFG)
end

if _LSP_SIG_CFG.bind then
vim.lsp.handlers['textDocument/signatureHelp'] =
vim.lsp.with(signature_handler, _LSP_SIG_CFG.handler_opts)
Expand Down Expand Up @@ -1184,6 +1180,17 @@ M.signature_handler = signature_handler
M.setup = function(cfg)
cfg = cfg or {}
M.deprecated(cfg)

if type(cfg) == 'table' then
if cfg.hint_prefix and type(cfg.hint_prefix) == 'string' then
cfg.hint_prefix = {
default = cfg.hint_prefix, -- when the hint is on the same line
}
end
_LSP_SIG_CFG = vim.tbl_extend('keep', cfg, _LSP_SIG_CFG)
cleanup_logs(cfg)
-- log(_LSP_SIG_CFG)
end
log('user cfg:', cfg)
local _start_client = vim.lsp.start_client
_LSP_SIG_VT_NS = api.nvim_create_namespace('lsp_signature_vt')
Expand Down