feat(lsp): support documentColor dynamic registration #33800

This commit is contained in:
Maria José Solano
2025-05-04 09:00:21 -05:00
committed by GitHub
parent 5c15df449a
commit 8f5bd569c5
5 changed files with 73 additions and 27 deletions

View File

@ -2212,14 +2212,11 @@ enable({enable}, {bufnr}, {opts}) *vim.lsp.document_color.enable()*
Enables document highlighting from the given language client in the given
buffer.
You can enable document highlighting from a supporting client as follows: >lua
You can enable document highlighting when a client attaches to a buffer as
follows: >lua
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client:supports_method('textDocument/documentColor') then
vim.lsp.document_color.enable(true, args.buf)
end
vim.lsp.document_color.enable(true, args.buf)
end
})
<

View File

@ -172,16 +172,6 @@ local function buf_clear(bufnr)
api.nvim__redraw({ buf = bufnr, valid = true, flush = false })
end
--- @param bufnr integer
--- @param client_id? integer
local function buf_refresh(bufnr, client_id)
util._refresh(ms.textDocument_documentColor, {
bufnr = bufnr,
handler = on_document_color,
client_id = client_id,
})
end
--- @param bufnr integer
local function buf_disable(bufnr)
buf_clear(bufnr)
@ -196,7 +186,7 @@ local function buf_enable(bufnr)
on_reload = function(_, buf)
buf_clear(buf)
if bufstates[buf].enabled then
buf_refresh(buf)
M._buf_refresh(buf)
end
end,
on_detach = function(_, buf)
@ -215,7 +205,7 @@ local function buf_enable(bufnr)
(method == ms.textDocument_didChange or method == ms.textDocument_didOpen)
and bufstates[args.buf].enabled
then
buf_refresh(args.buf, args.data.client_id)
M._buf_refresh(args.buf, args.data.client_id)
end
end,
})
@ -238,7 +228,18 @@ local function buf_enable(bufnr)
end,
})
buf_refresh(bufnr)
M._buf_refresh(bufnr)
end
--- @nodoc
--- @param bufnr integer
--- @param client_id? integer
function M._buf_refresh(bufnr, client_id)
util._refresh(ms.textDocument_documentColor, {
bufnr = bufnr,
handler = on_document_color,
client_id = client_id,
})
end
--- Query whether document colors are enabled in the given buffer.
@ -259,15 +260,11 @@ end
--- Enables document highlighting from the given language client in the given buffer.
---
--- You can enable document highlighting from a supporting client as follows:
--- You can enable document highlighting when a client attaches to a buffer as follows:
--- ```lua
--- vim.api.nvim_create_autocmd('LspAttach', {
--- callback = function(args)
--- local client = vim.lsp.get_client_by_id(args.data.client_id)
---
--- if client:supports_method('textDocument/documentColor') then
--- vim.lsp.document_color.enable(true, args.buf)
--- end
--- vim.lsp.document_color.enable(true, args.buf)
--- end
--- })
--- ```
@ -307,7 +304,7 @@ api.nvim_create_autocmd('ColorScheme', {
for _, bufnr in ipairs(api.nvim_list_bufs()) do
buf_clear(bufnr)
if api.nvim_buf_is_loaded(bufnr) and bufstates[bufnr].enabled then
buf_refresh(bufnr)
M._buf_refresh(bufnr)
else
reset_bufstate(bufnr, false)
end

View File

@ -128,6 +128,15 @@ RSC[ms.client_registerCapability] = function(_, params, ctx)
for bufnr in pairs(client.attached_buffers) do
vim.lsp._set_defaults(client, bufnr)
end
for _, reg in ipairs(params.registrations) do
if reg.method == ms.textDocument_documentColor then
for bufnr in pairs(client.attached_buffers) do
if vim.lsp.document_color.is_enabled(bufnr) then
vim.lsp.document_color._buf_refresh(bufnr, client.id)
end
end
end
end
return vim.NIL
end

View File

@ -533,7 +533,7 @@ function protocol.make_client_capabilities()
dynamicRegistration = false,
},
colorProvider = {
dynamicRegistration = false,
dynamicRegistration = true,
},
},
workspace = {

View File

@ -115,6 +115,49 @@ body {
screen:expect({ grid = grid_without_colors })
end)
it('supports dynamic registration', function()
local grid_with_dynamic_highlights = [[
body { |
{2:color}: {2:#FFF}; |
background-color: {3:rgb(0, 255, 255)}; |
} |
^ |
{1:~ }|*8
|
]]
exec_lua(function()
_G.server2 = _G._create_server({
colorProvider = {
documentSelector = nil,
},
handlers = {
['textDocument/documentColor'] = function(_, _, callback)
callback(nil, {
{
range = {
start = { line = 1, character = 2 },
['end'] = { line = 1, character = 7 },
},
color = { red = 1, green = 1, blue = 1 },
},
})
end,
},
})
local client_id2 = assert(vim.lsp.start({ name = 'dummy2', cmd = _G.server2.cmd }))
vim.lsp.handlers['client/registerCapability'](nil, {
registrations = {
{ id = 'documentColor', method = 'textDocument/documentColor' },
},
}, { client_id = client_id2, method = 'client/registerCapability' })
end)
screen:expect({ grid = grid_with_dynamic_highlights })
end)
it('does not clear document colors when one of several clients detaches', function()
local client_id2 = exec_lua(function()
_G.server2 = _G._create_server({