diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index d6ef761bcb..ec5e813a6d 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -528,6 +528,15 @@ LspCodeLens Used to color the virtual text of the codelens. See |nvim_buf_set_virtual_text()|. + *lsp-highlight-signature* + +Highlight groups related to |vim.lsp.handlers.signature_help()|. + + *hl-LspSignatureActiveParameter* +LspSignatureActiveParameter + Used to highlight the active parameter in the signature help. See + |vim.lsp.handlers.signature_help()|. + ============================================================================== AUTOCOMMANDS *lsp-autocommands* diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 41852b9d88..7da24d8c43 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -316,6 +316,7 @@ M['textDocument/typeDefinition'] = location_handler M['textDocument/implementation'] = location_handler --- |lsp-handler| for the method "textDocument/signatureHelp" +--- The active parameter is highlighted with |hl-LspSignatureActiveParameter| ---
 --- vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(
 ---   vim.lsp.handlers.signature_help, {
@@ -338,13 +339,17 @@ function M.signature_help(_, method, result, _, bufnr, config)
     return
   end
   local ft = api.nvim_buf_get_option(bufnr, 'filetype')
-  local lines = util.convert_signature_help_to_markdown_lines(result, ft)
+  local lines, hl = util.convert_signature_help_to_markdown_lines(result, ft)
   lines = util.trim_empty_lines(lines)
   if vim.tbl_isempty(lines) then
     print('No signature help available')
     return
   end
-  return util.open_floating_preview(lines, "markdown", config)
+  local fbuf, fwin = util.open_floating_preview(lines, "markdown", config)
+  if hl then
+    api.nvim_buf_add_highlight(fbuf, -1, "LspSignatureActiveParameter", 0, unpack(hl))
+  end
+  return fbuf, fwin
 end
 
 --@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index 7e43eb84de..6d02b9ba74 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -691,10 +691,11 @@ function protocol.make_client_capabilities()
       signatureHelp = {
         dynamicRegistration = false;
         signatureInformation = {
+          activeParameterSupport = true;
           documentationFormat = { protocol.MarkupKind.Markdown; protocol.MarkupKind.PlainText };
-          -- parameterInformation = {
-          --   labelOffsetSupport = false;
-          -- };
+          parameterInformation = {
+            labelOffsetSupport = true;
+          };
         };
       };
       references = {
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 06afc2c5e2..17440ca1b5 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -856,6 +856,7 @@ function M.convert_signature_help_to_markdown_lines(signature_help, ft)
   --=== 0`. Whenever possible implementors should make an active decision about
   --the active signature and shouldn't rely on a default value.
   local contents = {}
+  local active_hl
   local active_signature = signature_help.activeSignature or 0
   -- If the activeSignature is not inside the valid range, then clip it.
   if active_signature >= #signature_help.signatures then
@@ -875,7 +876,7 @@ function M.convert_signature_help_to_markdown_lines(signature_help, ft)
     M.convert_input_to_markdown_lines(signature.documentation, contents)
   end
   if signature.parameters and #signature.parameters > 0 then
-    local active_parameter = signature_help.activeParameter or 0
+    local active_parameter = (signature.activeParameter or signature_help.activeParameter or 0)
     -- If the activeParameter is not inside the valid range, then clip it.
     if active_parameter >= #signature.parameters then
       active_parameter = 0
@@ -900,13 +901,20 @@ function M.convert_signature_help_to_markdown_lines(signature_help, ft)
         documentation?: string | MarkupContent;
       }
       --]=]
-      -- TODO highlight parameter
+      if parameter.label then
+        if type(parameter.label) == "table" then
+          active_hl = parameter.label
+        else
+          local i = signature.label:find(parameter.label)
+          if i then active_hl = {i - 1, i + #parameter.label - 1} end
+        end
+      end
       if parameter.documentation then
         M.convert_input_to_markdown_lines(parameter.documentation, contents)
       end
     end
   end
-  return contents
+  return contents, active_hl
 end
 
 --- Creates a table with sensible default options for a floating window. The