diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 9270726a0b..bcd64e9cd9 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -87,6 +87,11 @@ LSP • `vim.lsp.semantic_tokens.start/stop` now renamed to `vim.lsp.semantic_tokens.enable` • Missing fields in LSP messages are now represented using |vim.NIL| instead of nil. +• |vim.lsp.util.convert_signature_help_to_markdown_lines()| activeParameter + handling updated: + • Values < 0 are now treated as `nil` instead of 0. + • Values outside the range of `signatures[activeSignature].parameters` + are now treated as `nil` instead of `#signatures[activeSignature].parameters` LUA @@ -222,6 +227,7 @@ LSP https://microsoft.github.io/language-server-protocol/specification/#textDocument_linkedEditingRange • Support for related documents in pull diagnostics: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#relatedFullDocumentDiagnosticReport +• |vim.lsp.buf.signature_help()| supports "noActiveParameterSupport". LUA diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 6dc90f7184..86b456546e 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -330,8 +330,8 @@ local function process_signature_help_results(results) ) api.nvim_command('redraw') else - local result = r.result --- @type lsp.SignatureHelp - if result and result.signatures and result.signatures[1] then + local result = r.result + if result and result.signatures then for i, sig in ipairs(result.signatures) do sig.activeParameter = sig.activeParameter or result.activeParameter local idx = #signatures + 1 diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index fd3d192431..30b993c1cc 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -514,6 +514,7 @@ function protocol.make_client_capabilities() dynamicRegistration = false, signatureInformation = { activeParameterSupport = true, + noActiveParameterSupport = true, documentationFormat = { constants.MarkupKind.Markdown, constants.MarkupKind.PlainText }, parameterInformation = { labelOffsetSupport = true, diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 753dbad9c4..6c3641e627 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -829,18 +829,21 @@ function M.convert_signature_help_to_markdown_lines(signature_help, ft, triggers M.convert_input_to_markdown_lines(signature.documentation, contents) end if signature.parameters and #signature.parameters > 0 then - -- First check if the signature has an activeParameter. If it doesn't check if the response - -- had that property instead. Else just default to 0. - -- - -- NOTE: Using tonumber() as a temporary workaround to handle `vim.NIL` until #34838 is merged - local active_parameter = math.max( - tonumber(signature.activeParameter) or tonumber(signature_help.activeParameter) or 0, - 0 - ) + local active_parameter = signature.activeParameter or signature_help.activeParameter - -- If the activeParameter is > #parameters, then set it to the last - -- NOTE: this is not fully according to the spec, but a client-side interpretation - active_parameter = math.min(active_parameter, #signature.parameters - 1) + -- NOTE: We intentionally violate the LSP spec, which states that if `activeParameter` + -- is not provided or is out-of-bounds, it should default to 0. + -- Instead, we default to `nil`, as most clients do. In practice, 'no active parameter' + -- is better default than 'first parameter' and aligns better with user expectations. + -- Related discussion: https://github.com/microsoft/language-server-protocol/issues/1271 + if + not active_parameter + or active_parameter == vim.NIL + or active_parameter < 0 + or active_parameter >= #signature.parameters + then + return contents, nil + end local parameter = signature.parameters[active_parameter + 1] local parameter_label = parameter.label