mirror of
https://github.com/neovim/neovim.git
synced 2026-04-02 13:49:27 +00:00
feat(lsp): show color preview in completion items #32138
Problem: Color completion items display as plain text without visual preview Solution: Parse RGB/hex colors from documentation and render with colored symbol ■
This commit is contained in:
@@ -315,6 +315,7 @@ LSP
|
|||||||
• Support for `workspace/codeLens/refresh`:
|
• Support for `workspace/codeLens/refresh`:
|
||||||
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#codeLens_refresh
|
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#codeLens_refresh
|
||||||
• `gx` will use `textDocument/documentLink` if available.
|
• `gx` will use `textDocument/documentLink` if available.
|
||||||
|
• |vim.lsp.completion.enable()| adds colored symbol preview for color items.
|
||||||
|
|
||||||
LUA
|
LUA
|
||||||
|
|
||||||
|
|||||||
@@ -277,6 +277,51 @@ local function match_item_by_value(value, prefix)
|
|||||||
return vim.startswith(value, prefix), nil
|
return vim.startswith(value, prefix), nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Generate kind text for completion color items
|
||||||
|
--- Parse color from doc and return colored symbol ■
|
||||||
|
---
|
||||||
|
---@param item table completion item with kind and documentation
|
||||||
|
---@return string? kind text or "■" for colors
|
||||||
|
---@return string? highlight group for colors
|
||||||
|
local function generate_kind(item)
|
||||||
|
if not lsp.protocol.CompletionItemKind[item.kind] then
|
||||||
|
return 'Unknown'
|
||||||
|
end
|
||||||
|
if item.kind ~= lsp.protocol.CompletionItemKind.Color then
|
||||||
|
return lsp.protocol.CompletionItemKind[item.kind]
|
||||||
|
end
|
||||||
|
local doc = get_doc(item)
|
||||||
|
if #doc == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- extract hex from RGB format
|
||||||
|
local r, g, b = doc:match('rgb%((%d+)%s*,?%s*(%d+)%s*,?%s*(%d+)%)')
|
||||||
|
local hex = r and string.format('%02x%02x%02x', tonumber(r), tonumber(g), tonumber(b))
|
||||||
|
or doc:match('#?([%da-fA-F]+)')
|
||||||
|
|
||||||
|
if not hex then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- expand 3-digit hex to 6-digit
|
||||||
|
if #hex == 3 then
|
||||||
|
hex = hex:gsub('.', '%1%1')
|
||||||
|
end
|
||||||
|
|
||||||
|
if #hex ~= 6 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
hex = hex:lower()
|
||||||
|
local group = ('@lsp.color.%s'):format(hex)
|
||||||
|
if #api.nvim_get_hl(0, { name = group }) == 0 then
|
||||||
|
api.nvim_set_hl(0, group, { fg = '#' .. hex })
|
||||||
|
end
|
||||||
|
|
||||||
|
return '■', group
|
||||||
|
end
|
||||||
|
|
||||||
--- Turns the result of a `textDocument/completion` request into vim-compatible
|
--- Turns the result of a `textDocument/completion` request into vim-compatible
|
||||||
--- |complete-items|.
|
--- |complete-items|.
|
||||||
---
|
---
|
||||||
@@ -359,16 +404,18 @@ function M._lsp_to_complete_items(
|
|||||||
then
|
then
|
||||||
hl_group = 'DiagnosticDeprecated'
|
hl_group = 'DiagnosticDeprecated'
|
||||||
end
|
end
|
||||||
|
local kind, kind_hlgroup = generate_kind(item)
|
||||||
local completion_item = {
|
local completion_item = {
|
||||||
word = word,
|
word = word,
|
||||||
abbr = item.label,
|
abbr = item.label,
|
||||||
kind = protocol.CompletionItemKind[item.kind] or 'Unknown',
|
kind = kind,
|
||||||
menu = item.detail or '',
|
menu = item.detail or '',
|
||||||
info = get_doc(item),
|
info = get_doc(item),
|
||||||
icase = 1,
|
icase = 1,
|
||||||
dup = 1,
|
dup = 1,
|
||||||
empty = 1,
|
empty = 1,
|
||||||
abbr_hlgroup = hl_group,
|
abbr_hlgroup = hl_group,
|
||||||
|
kind_hlgroup = kind_hlgroup,
|
||||||
user_data = {
|
user_data = {
|
||||||
nvim = {
|
nvim = {
|
||||||
lsp = {
|
lsp = {
|
||||||
|
|||||||
@@ -171,6 +171,21 @@ describe('vim.lsp.completion: item conversion', function()
|
|||||||
eq(expected, got)
|
eq(expected, got)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('generate "■" symbol with highlight group for CompletionItemKind.Color', function()
|
||||||
|
local completion_list = {
|
||||||
|
{ label = 'text-red-300', kind = 16, documentation = 'color: rgb(252, 165, 165)' },
|
||||||
|
}
|
||||||
|
local result = complete('|', completion_list)
|
||||||
|
result = vim.tbl_map(function(x)
|
||||||
|
return {
|
||||||
|
word = x.word,
|
||||||
|
kind_hlgroup = x.kind_hlgroup,
|
||||||
|
kind = x.kind,
|
||||||
|
}
|
||||||
|
end, result.items)
|
||||||
|
eq({ { word = 'text-red-300', kind_hlgroup = '@lsp.color.fca5a5', kind = '■' } }, result)
|
||||||
|
end)
|
||||||
|
|
||||||
---@param prefix string
|
---@param prefix string
|
||||||
---@param items lsp.CompletionItem[]
|
---@param items lsp.CompletionItem[]
|
||||||
---@param expected table[]
|
---@param expected table[]
|
||||||
|
|||||||
Reference in New Issue
Block a user