commit 729111d3a3cd4939b3c24925cf1e0d7befec483e
parent 2ac00f13502fbe564a0406439126552161295b4f
Author: Robert Muir <rmuir@apache.org>
Date: Wed, 27 Aug 2025 21:51:30 -0400
fix(lsp): don't treat MarkedString[] with language id as empty #35518
Problem:
Hover response of MarkedString[] where the first element contains a
language identifier treated as empty.
Solution:
Fix empty check to handle case of MarkedString[] where the first element
is a pair of a language and value.
Diffstat:
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua
@@ -69,11 +69,26 @@ function M.hover(config)
lsp.log.error(err.code, err.message)
elseif result and result.contents then
-- Make sure the response is not empty
+ -- Five response shapes:
+ -- - MarkupContent: { kind="markdown", value="doc" }
+ -- - MarkedString-string: "doc"
+ -- - MarkedString-pair: { language="c", value="doc" }
+ -- - MarkedString[]-string: { "doc1", ... }
+ -- - MarkedString[]-pair: { { language="c", value="doc1" }, ... }
if
(
type(result.contents) == 'table'
- and #(vim.tbl_get(result.contents, 'value') or result.contents[1] or '') > 0
- ) or (type(result.contents) == 'string' and #result.contents > 0)
+ and #(
+ vim.tbl_get(result.contents, 'value') -- MarkupContent or MarkedString-pair
+ or vim.tbl_get(result.contents, 1, 'value') -- MarkedString[]-pair
+ or result.contents[1] -- MarkedString[]-string
+ or ''
+ )
+ > 0
+ )
+ or (
+ type(result.contents) == 'string' and #result.contents > 0 -- MarkedString-string
+ )
then
results1[client_id] = result
else
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
@@ -7139,5 +7139,33 @@ describe('LSP', function()
eq('Empty hover response', n.exec_capture('lua vim.lsp.buf.hover()'))
end)
+
+ it('treats markedstring array as not empty', function()
+ exec_lua(create_server_definition)
+ exec_lua(function()
+ local server = _G._create_server({
+ capabilities = {
+ hoverProvider = true,
+ },
+ handlers = {
+ ['textDocument/hover'] = function(_, _, callback)
+ local res = {
+ contents = {
+ {
+ language = 'java',
+ value = 'Example',
+ },
+ 'doc comment',
+ },
+ }
+ callback(nil, res)
+ end,
+ },
+ })
+ vim.lsp.start({ name = 'dummy', cmd = server.cmd })
+ end)
+
+ eq('', n.exec_capture('lua vim.lsp.buf.hover()'))
+ end)
end)
end)