mirror of
https://github.com/neovim/neovim.git
synced 2026-07-13 04:40:42 +00:00
fix(lsp): limit number of created highlight groups (#39133)
* fix(api): allow silencing "Too many highlight groups" error
Problem: Using Lua's `vim.api.nvim_set_hl(0, 'New', {...})` can fail if
there are too many existing highlight groups. However, this error can
not be silenced with `pcall`.
Solution: Make it possible to silence in `nvim_set_hl` and
`nvim_get_hl_id_by_name`.
* fix(lsp): limit number of groups created by `document_color()`
Problem: A file can contain many string colors that would be highlighted
by an LSP server. If this number crosses 19999 (maximum number of
allowed highlight groups), there are general issues with creating
other highlight groups, which can break functionality outside of
`vim.lsp.document_color`.
Solution: Limit number of highlight groups that are created by
`vim.lsp.document_color` to 10000 (half of allowed maximum).
This is not a 100% solution (since there can exist more than 10000
other highlight groups), but explicitly checking number of groups is
slow and 10000 should (hopefully) be enough for most use cases.
This commit is contained in:
committed by
GitHub
parent
eb569a695f
commit
7219b816ea
@@ -65,12 +65,13 @@ end
|
||||
--- Cache of the highlight groups that we've already created.
|
||||
--- @type table<string, true>
|
||||
local color_cache = {}
|
||||
local n_color_cache = 0
|
||||
|
||||
--- Gets or creates the highlight group for the given LSP color information.
|
||||
---
|
||||
--- @param hex_code string
|
||||
--- @param style string
|
||||
--- @return string
|
||||
--- @return string?
|
||||
local function get_hl_group(hex_code, style)
|
||||
if style ~= 'background' then
|
||||
style = 'foreground'
|
||||
@@ -78,17 +79,23 @@ local function get_hl_group(hex_code, style)
|
||||
|
||||
local hl_name = ('LspDocumentColor_%s_%s'):format(hex_code:sub(2), style)
|
||||
|
||||
if not color_cache[hl_name] then
|
||||
if style == 'background' then
|
||||
api.nvim_set_hl(0, hl_name, { bg = hex_code, fg = get_contrast_color(hex_code) })
|
||||
else
|
||||
api.nvim_set_hl(0, hl_name, { fg = hex_code })
|
||||
end
|
||||
|
||||
color_cache[hl_name] = true
|
||||
if color_cache[hl_name] then
|
||||
return hl_name
|
||||
end
|
||||
|
||||
return hl_name
|
||||
-- Limit number of created highlight groups to 10000 to not approach near
|
||||
-- a hard limit of 19999 highlight groups (`:h E849`)
|
||||
if n_color_cache > 10000 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local hl_opts = style == 'background' and { bg = hex_code, fg = get_contrast_color(hex_code) }
|
||||
or { fg = hex_code }
|
||||
local ok = pcall(api.nvim_set_hl, 0, hl_name, hl_opts)
|
||||
color_cache[hl_name] = ok
|
||||
n_color_cache = n_color_cache + (ok and 1 or 0)
|
||||
|
||||
return ok and hl_name or nil
|
||||
end
|
||||
|
||||
--- @class (private) vim.lsp.document_color.Provider : vim.lsp.Capability
|
||||
@@ -138,6 +145,7 @@ function Provider:new(bufnr)
|
||||
desc = 'Refresh document_color',
|
||||
callback = function()
|
||||
color_cache = {}
|
||||
n_color_cache = 0
|
||||
local provider = Provider.active[bufnr]
|
||||
if provider then
|
||||
provider:clear()
|
||||
|
||||
Reference in New Issue
Block a user