mirror of
https://github.com/neovim/neovim.git
synced 2025-10-26 12:27:24 +00:00
fix(lsp): properly handle documentColor from multiple servers #33656
This commit is contained in:
committed by
GitHub
parent
ef16a02a76
commit
b98aefc584
@@ -15,13 +15,16 @@ local M = {}
|
||||
|
||||
--- @class (private) vim.lsp.document_color.BufState
|
||||
--- @field enabled boolean Whether document_color is enabled for the current buffer
|
||||
--- @field buf_version? integer Buffer version for which the color ranges correspond to
|
||||
--- @field processed_version table<integer, integer?> (client_id -> buffer version) Buffer version for which the color ranges correspond to
|
||||
--- @field applied_version table<integer, integer?> (client_id -> buffer version) Last buffer version for which we applied color ranges
|
||||
--- @field hl_info table<integer, vim.lsp.document_color.HighlightInfo[]?> (client_id -> color highlights) Processed highlight information
|
||||
|
||||
--- @type table<integer, vim.lsp.document_color.BufState?>
|
||||
local bufstates = {}
|
||||
|
||||
--- @type table<integer, integer> (client_id -> namespace ID) documentColor namespace ID for each client.
|
||||
local client_ns = {}
|
||||
|
||||
--- @inlinedoc
|
||||
--- @class vim.lsp.document_color.enable.Opts
|
||||
---
|
||||
@@ -91,7 +94,13 @@ end
|
||||
--- @param bufnr integer
|
||||
--- @param enabled boolean
|
||||
local function reset_bufstate(bufnr, enabled)
|
||||
bufstates[bufnr] = { enabled = enabled, applied_version = {}, hl_info = {} }
|
||||
bufstates[bufnr] = {
|
||||
enabled = enabled,
|
||||
processed_version = {},
|
||||
applied_version = {},
|
||||
hl_info = {},
|
||||
ns = {},
|
||||
}
|
||||
end
|
||||
|
||||
--- |lsp-handler| for the `textDocument/documentColor` method.
|
||||
@@ -118,6 +127,10 @@ local function on_document_color(err, result, ctx)
|
||||
return
|
||||
end
|
||||
|
||||
if not client_ns[client_id] then
|
||||
client_ns[client_id] = api.nvim_create_namespace('nvim.lsp.document_color.client_' .. client_id)
|
||||
end
|
||||
|
||||
local hl_infos = {} --- @type vim.lsp.document_color.HighlightInfo[]
|
||||
local style = document_color_opts.style
|
||||
for _, res in ipairs(result) do
|
||||
@@ -136,9 +149,10 @@ local function on_document_color(err, result, ctx)
|
||||
|
||||
table.insert(hl_infos, hl_info)
|
||||
end
|
||||
bufstate.hl_info[client_id] = hl_infos
|
||||
|
||||
bufstate.buf_version = ctx.version
|
||||
bufstate.hl_info[client_id] = hl_infos
|
||||
bufstate.processed_version[client_id] = ctx.version
|
||||
|
||||
api.nvim__redraw({ buf = bufnr, valid = true, flush = false })
|
||||
end
|
||||
|
||||
@@ -147,11 +161,11 @@ local function buf_clear(bufnr)
|
||||
local bufstate = assert(bufstates[bufnr])
|
||||
local client_ids = vim.tbl_keys(bufstate.hl_info) --- @type integer[]
|
||||
|
||||
for _, id in ipairs(client_ids) do
|
||||
bufstate.hl_info[id] = {}
|
||||
for _, client_id in ipairs(client_ids) do
|
||||
bufstate.hl_info[client_id] = {}
|
||||
api.nvim_buf_clear_namespace(bufnr, client_ns[client_id], 0, -1)
|
||||
end
|
||||
|
||||
api.nvim_buf_clear_namespace(bufnr, document_color_ns, 0, -1)
|
||||
api.nvim__redraw({ buf = bufnr, valid = true, flush = false })
|
||||
end
|
||||
|
||||
@@ -305,26 +319,20 @@ api.nvim_set_decoration_provider(document_color_ns, {
|
||||
end
|
||||
local bufstate = assert(bufstates[bufnr])
|
||||
|
||||
local all_applied = #bufstate.applied_version > 0
|
||||
and vim.iter(pairs(bufstate.applied_version)):all(function(_, buf_version)
|
||||
return buf_version == bufstate.buf_version
|
||||
end)
|
||||
|
||||
if bufstate.buf_version ~= util.buf_versions[bufnr] or all_applied then
|
||||
return
|
||||
end
|
||||
|
||||
api.nvim_buf_clear_namespace(bufnr, document_color_ns, 0, -1)
|
||||
|
||||
local style = document_color_opts.style
|
||||
|
||||
for client_id, client_hls in pairs(bufstate.hl_info) do
|
||||
if bufstate.applied_version[client_id] ~= bufstate.buf_version then
|
||||
if
|
||||
bufstate.processed_version[client_id] == util.buf_versions[bufnr]
|
||||
and bufstate.processed_version[client_id] ~= bufstate.applied_version[client_id]
|
||||
then
|
||||
api.nvim_buf_clear_namespace(bufnr, client_ns[client_id], 0, -1)
|
||||
|
||||
for _, hl in ipairs(client_hls) do
|
||||
if type(style) == 'function' then
|
||||
style(bufnr, hl.range, hl.hex_code)
|
||||
elseif style == 'foreground' or style == 'background' then
|
||||
api.nvim_buf_set_extmark(bufnr, document_color_ns, hl.range[1], hl.range[2], {
|
||||
api.nvim_buf_set_extmark(bufnr, client_ns[client_id], hl.range[1], hl.range[2], {
|
||||
end_row = hl.range[3],
|
||||
end_col = hl.range[4],
|
||||
hl_group = hl.hl_group,
|
||||
@@ -333,14 +341,14 @@ api.nvim_set_decoration_provider(document_color_ns, {
|
||||
else
|
||||
-- Default swatch: \uf0c8
|
||||
local swatch = style == 'virtual' and ' ' or style
|
||||
api.nvim_buf_set_extmark(bufnr, document_color_ns, hl.range[1], hl.range[2], {
|
||||
api.nvim_buf_set_extmark(bufnr, client_ns[client_id], hl.range[1], hl.range[2], {
|
||||
virt_text = { { swatch, hl.hl_group } },
|
||||
virt_text_pos = 'inline',
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
bufstate.applied_version[client_id] = bufstate.buf_version
|
||||
bufstate.applied_version[client_id] = bufstate.processed_version[client_id]
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
Reference in New Issue
Block a user