Skip to content

Commit

Permalink
feat: added suport for Luasnip jump targets to signature help
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Oct 27, 2022
1 parent feaf5c4 commit c09d197
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 71 deletions.
13 changes: 12 additions & 1 deletion lua/noice/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,12 @@ function M.defaults()
},
signature = {
enabled = false,
auto_open = true, -- Automatically show signature help when typing a trigger character from the LSP
auto_open = {
enabled = true,
trigger = true, -- Automatically show signature help when typing a trigger character from the LSP
luasnip = true, -- Will open signature help when jumping to Luasnip insert nodes
throttle = 50, -- Debounce lsp signature help request by 50ms
},
view = nil, -- when nil, use defaults from documentation
---@type NoiceViewOptions
opts = {}, -- merged with defaults from documentation
Expand Down Expand Up @@ -214,7 +219,13 @@ function M.setup(options)
M._running = true
end

---@param opts NoiceConfig
function M.fix_legacy(opts)
if opts.lsp and opts.lsp.signature and type(opts.lsp.signature.auto_open) == "boolean" then
opts.lsp.signature.auto_open = {
enabled = opts.lsp.signature.auto_open,
}
end
if opts.lsp_progress then
opts.lsp = opts.lsp or {}
opts.lsp.progress = opts.lsp_progress
Expand Down
71 changes: 33 additions & 38 deletions lua/noice/source/lsp/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ end

function M.setup()
M.hover = Util.protect(M.hover)

local group = vim.api.nvim_create_augroup("noice_lsp", {
clear = true,
})

if Config.options.lsp.hover.enabled then
vim.lsp.handlers["textDocument/hover"] = M.hover
end
Expand All @@ -42,13 +47,30 @@ function M.setup()
vim.lsp.handlers["textDocument/signatureHelp"] = M.signature
end

if Config.options.lsp.signature.auto_open then
require("noice.source.lsp.signature").setup()
if Config.options.lsp.signature.auto_open.enabled then
require("noice.source.lsp.signature").setup(group)
end

if Config.options.lsp.progress.enabled then
require("noice.source.lsp.progress").setup()
end

vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI", "InsertCharPre" }, {
group = group,
callback = function()
vim.defer_fn(M.on_close, 10)
end,
})
end

function M.on_close()
for _, message in pairs(M._messages) do
-- close the message if we're not in it's buffer (focus)
local keep = message:on_buf(vim.api.nvim_get_current_buf()) or (message.opts.stay and message.opts.stay())
if not keep then
M.hide(message)
end
end
end

function M.scroll(delta)
Expand All @@ -63,51 +85,27 @@ function M.scroll(delta)
end

---@param message NoiceMessage
function M.augroup(message)
return "noice_lsp_" .. message.id
end

---@param message NoiceMessage
function M.close(message)
pcall(vim.api.nvim_del_augroup_by_name, M.augroup(message))
function M.hide(message)
message.opts.keep = function()
return false
end
Manager.remove(message)
end

---@param message NoiceMessage
---@param keep? fun():boolean
function M.auto_close(message, keep)
---@param stay? fun():boolean
function M.show(message, stay)
message.opts.timeout = 100
message.opts.keep = function()
return true
end

local group = vim.api.nvim_create_augroup(M.augroup(message), {
clear = true,
})

vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI", "InsertCharPre" }, {
group = group,
callback = function()
if keep and keep() then
return
end
if not message:on_buf(vim.api.nvim_get_current_buf()) then
M.close(message)
end
end,
})
end

---@param message NoiceMessage
function M.close_others(message)
message.opts.stay = stay
for _, m in pairs(M._messages) do
if m ~= message then
M.close(m)
M.hide(m)
end
end
Manager.add(message)
end

---@param result SignatureHelp
Expand All @@ -121,14 +119,12 @@ function M.signature(_, result, ctx, config)
end

local message = M.get(M.kinds.signature)
M.close_others(message)

if config.trigger or not message:focus() then
result.ft = vim.bo[ctx.bufnr].filetype
result.message = message
Signature.new(result):format()
M.auto_close(message, config.keep)
Manager.add(message)
M.show(message, config.stay)
end
end

Expand All @@ -139,11 +135,10 @@ function M.hover(_, result)
end

local message = M.get(M.kinds.hover)
M.close_others(message)

if not message:focus() then
Format.format(message, result.contents)
M.auto_close(message)
Manager.add(message)
M.show(message)
end
end

Expand Down
72 changes: 41 additions & 31 deletions lua/noice/source/lsp/signature.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ local require = require("noice.util.lazy")
local NoiceText = require("noice.text")
local Format = require("noice.source.lsp.format")
local Markdown = require("noice.text.markdown")
local Lsp = require("noice.source.lsp")
local Config = require("noice.config")
local Util = require("noice.util")

---@class SignatureInformation
---@field label string
Expand Down Expand Up @@ -37,9 +38,8 @@ M.trigger_kind = {
content_change = 3,
}

-- TODO: add scroll up/down
-- TODO: document add scroll up/down
-- TODO: horz line for Hover should overlap end of code block
-- TODO: positioning of the signature help window

function M.get_char(buf)
local win = vim.fn.bufwinid(buf)
Expand All @@ -51,47 +51,57 @@ function M.get_char(buf)
return line:sub(-1, -1)
end

function M.setup()
function M.setup(group)
vim.api.nvim_create_autocmd("LspAttach", {
group = group,
callback = function(args)
local buf = args.buf
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client.server_capabilities.signatureHelpProvider then
local chars = client.server_capabilities.signatureHelpProvider.triggerCharacters
if #chars > 0 then
vim.api.nvim_create_autocmd({ "TextChangedI", "TextChangedP", "InsertEnter" }, {
buffer = buf,
callback = function()
if vim.api.nvim_get_current_buf() ~= buf then
return
end
local message = Lsp.get(Lsp.kinds.signature)
if message:win() then
-- no need to fetch signature when signature is already shown
return
end
if vim.tbl_contains(chars, M.get_char(buf)) then
local params = vim.lsp.util.make_position_params(0, client.offset_encoding)
vim.lsp.buf_request(
buf,
"textDocument/signatureHelp",
params,
vim.lsp.with(require("noice.source.lsp").signature, {
trigger = true,
keep = function()
return vim.tbl_contains(chars, M.get_char(buf))
end,
})
)
end
end,
})
local callback = M.check(buf, chars, client.offset_encoding)
if Config.options.lsp.signature.auto_open.luasnip then
vim.api.nvim_create_autocmd("User", {
pattern = "LuasnipInsertNodeEnter",
callback = callback,
})
end
if Config.options.lsp.signature.auto_open.trigger then
vim.api.nvim_create_autocmd({ "TextChangedI", "TextChangedP", "InsertEnter" }, {
buffer = buf,
callback = callback,
})
end
end
end
end,
})
end

function M.check(buf, chars, encoding)
return Util.debounce(Config.options.lsp.signature.auto_open.throttle, function(_event)
if vim.api.nvim_get_current_buf() ~= buf then
return
end

if vim.tbl_contains(chars, M.get_char(buf)) then
local params = vim.lsp.util.make_position_params(0, encoding)
vim.lsp.buf_request(
buf,
"textDocument/signatureHelp",
params,
vim.lsp.with(require("noice.source.lsp").signature, {
trigger = true,
stay = function()
return vim.tbl_contains(chars, M.get_char(buf))
end,
})
)
end
end)
end

---@param help SignatureHelp
function M.new(help)
return setmetatable(help, M)
Expand Down
2 changes: 1 addition & 1 deletion lua/noice/view/backend/notify.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ local Manager = require("noice.message.manager")
---@field level? string|number Message log level
---@field merge boolean Merge messages into one Notification or create separate notifications
---@field replace boolean Replace existing notification or create a new one
---@field render? notify.RenderFun
---@field render? notify.RenderFun|string
---@field timeout? integer
local defaults = {
title = "Notification",
Expand Down

0 comments on commit c09d197

Please sign in to comment.