summaryrefslogtreecommitdiffstatshomepage
path: root/runtime/lua/vim/lsp/completion.lua
diff options
context:
space:
mode:
authorglepnir <glephunter@gmail.com>2026-02-28 23:02:52 +0800
committerGitHub <noreply@github.com>2026-02-28 10:02:52 -0500
commit3e8a4e10920dc6431547035eec514cdd21e37a3a (patch)
tree9cb3027850d8da061ca82cb834a3577acd88eb22 /runtime/lua/vim/lsp/completion.lua
parentc1e60f36f3fb915bb59503dedd330addb63161ac (diff)
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 ■
Diffstat (limited to 'runtime/lua/vim/lsp/completion.lua')
-rw-r--r--runtime/lua/vim/lsp/completion.lua49
1 files changed, 48 insertions, 1 deletions
diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua
index 119d1d77bb..adf198b164 100644
--- a/runtime/lua/vim/lsp/completion.lua
+++ b/runtime/lua/vim/lsp/completion.lua
@@ -277,6 +277,51 @@ local function match_item_by_value(value, prefix)
return vim.startswith(value, prefix), nil
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
--- |complete-items|.
---
@@ -359,16 +404,18 @@ function M._lsp_to_complete_items(
then
hl_group = 'DiagnosticDeprecated'
end
+ local kind, kind_hlgroup = generate_kind(item)
local completion_item = {
word = word,
abbr = item.label,
- kind = protocol.CompletionItemKind[item.kind] or 'Unknown',
+ kind = kind,
menu = item.detail or '',
info = get_doc(item),
icase = 1,
dup = 1,
empty = 1,
abbr_hlgroup = hl_group,
+ kind_hlgroup = kind_hlgroup,
user_data = {
nvim = {
lsp = {