Out of box, this plugin reconsturct completion_item and applies Treesitter highlight queries to produce richly colorized completion items with variable-size highlight ranges, somehow similar to lspkind.nvim.
Highly beta.
run nvim -u ~/.config/nvim/repro.lua ~/.config/nvim/repro.lua
as a minimal reproduce template
see repro.lua
Has built-in supports for rust, go, typescript, lua, c, for any other language, default to directly apply treesitter highlight to label (feel free to open feature request for more languages).
Currently supports nvim-cmp and blink.cmp.
With lazy.nvim:
return {
"xzbdmw/colorful-menu.nvim",
config = function()
-- You don't need to set these options.
require("colorful-menu").setup({
ft = {
lua = {
-- Maybe you want to dim arguments a bit.
auguments_hl = "@comment",
},
go = {
-- When true, label for field and variable will format like "foo: Foo"
-- instead of go's original syntax "foo Foo".
add_colon_before_type = false,
},
typescript = {
-- Add more filetype when needed, these three taken from lspconfig are default value.
enabled = { "typescript", "typescriptreact", "typescript.tsx" },
-- Or "vtsls", their information is different, so we
-- need to know in advance.
ls = "typescript-language-server",
extra_info_hl = "@comment",
},
rust = {
-- Such as (as Iterator), (use std::io).
extra_info_hl = "@comment",
},
c = {
-- Such as "From <stdio.h>"
extra_info_hl = "@comment",
},
-- If true, try to highlight "not supported" languages.
fallback = true,
},
-- If the built-in logic fails to find a suitable highlight group,
-- this highlight is applied to the label.
fallback_highlight = "@variable",
-- If provided, the plugin truncates the final displayed text to
-- this width (measured in display cells). Any highlights that extend
-- beyond the truncation point are ignored. Default 60.
max_width = 60,
})
end,
}
formatting = {
fields = { "kind", "abbr", "menu" },
format = function(entry, vim_item)
local completion_item = entry:get_completion_item()
local highlights_info =
require("colorful-menu").highlights(completion_item, vim.bo.filetype)
-- error, such as missing parser, fallback to use raw label.
if highlights_info == nil then
vim_item.abbr = completion_item.label
else
vim_item.abbr_hl_group = highlights_info.highlights
vim_item.abbr = highlights_info.text
end
local kind = require("lspkind").cmp_format({
mode = "symbol_text",
})(entry, vim_item)
local strings = vim.split(kind.kind, "%s", { trimempty = true })
vim_item.kind = " " .. (strings[1] or "") .. " "
vim_item.menu = ""
return vim_item
end,
}
config = function()
require("blink.cmp").setup({
completion = {
menu = {
draw = {
components = {
label = {
width = { fill = true, max = 60 },
text = function(ctx)
local highlights_info =
require("colorful-menu").highlights(ctx.item, vim.bo.filetype)
if highlights_info ~= nil then
return highlights_info.text
else
return ctx.label
end
end,
highlight = function(ctx)
local highlights_info =
require("colorful-menu").highlights(ctx.item, vim.bo.filetype)
local highlights = {}
if highlights_info ~= nil then
for _, info in ipairs(highlights_info.highlights) do
table.insert(highlights, {
info.range[1],
info.range[2],
group = ctx.deprecated and "BlinkCmpLabelDeprecated" or info[1],
})
end
end
for _, idx in ipairs(ctx.label_matched_indices) do
table.insert(highlights, { idx, idx + 1, group = "BlinkCmpLabelMatch" })
end
return highlights
end,
},
},
},
},
},
})
end,
Click to see video
https://github.com/user-attachments/assets/725ea273-b598-4947-b189-f642fa51cf9b)](https://github.com/user-attachments/assets/1e5b1587-4374-49c3-88e7-1e8ed37b3210Feel free to open issues or submit pull requests if you encounter any bugs or have feature requests.
MIT License.
Zed for the initial idea of colorize.
@David van Munster for the pr which make this plugin possible.