Skip to content

xzbdmw/colorful-menu.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

README

colorful-menu.nvim

image

Out of box, this plugin reconstructs completion item and applies treesitter highlight queries to produce richly colorized completion items with variable-size highlight ranges.

Has built-in support for

For other languages, it defaults to use highlight group of item's kind. (feel free to open feature request for more languages)

Currently supports nvim-cmp and blink.cmp.

Installation

With lazy.nvim:

return {
    "xzbdmw/colorful-menu.nvim",
    config = function()
        -- You don't need to set these options.
        require("colorful-menu").setup({
            ls = {
                lua_ls = {
                    -- Maybe you want to dim arguments a bit.
                    arguments_hl = "@comment",
                },
                gopls = {
                    -- By default, we render variable/function's type in the right most side,
                    -- to make them not to crowd together with the original label.

                    -- when true:
                    -- foo             *Foo
                    -- ast         "go/ast"

                    -- when false:
                    -- foo *Foo
                    -- ast "go/ast"
                    align_type_to_right = true,
                    -- When true, label for field and variable will format like "foo: Foo"
                    -- instead of go's original syntax "foo Foo". If align_type_to_right is
                    -- true, this option has no effect.
                    add_colon_before_type = false,
                    -- See https://github.com/xzbdmw/colorful-menu.nvim/pull/36
                    preserve_type_when_truncate = true,
                },
                -- for lsp_config or typescript-tools
                ts_ls = {
                    -- false means do not include any extra info,
                    -- see https://github.com/xzbdmw/colorful-menu.nvim/issues/42
                    extra_info_hl = "@comment",
                },
                vtsls = {
                    -- false means do not include any extra info,
                    -- see https://github.com/xzbdmw/colorful-menu.nvim/issues/42
                    extra_info_hl = "@comment",
                },
                ["rust-analyzer"] = {
                    -- Such as (as Iterator), (use std::io).
                    extra_info_hl = "@comment",
                    -- Similar to the same setting of gopls.
                    align_type_to_right = true,
                    -- See https://github.com/xzbdmw/colorful-menu.nvim/pull/36
                    preserve_type_when_truncate = true,
                },
                clangd = {
                    -- Such as "From <stdio.h>".
                    extra_info_hl = "@comment",
                    -- Similar to the same setting of gopls.
                    align_type_to_right = true,
                    -- the hl group of leading dot of "•std::filesystem::permissions(..)"
                    import_dot_hl = "@comment",
                    -- See https://github.com/xzbdmw/colorful-menu.nvim/pull/36
                    preserve_type_when_truncate = true,
                },
                zls = {
                    -- Similar to the same setting of gopls.
                    align_type_to_right = true,
                },
                roslyn = {
                    extra_info_hl = "@comment",
                },
                dartls = {
                    extra_info_hl = "@comment",
                },
                -- The same applies to pyright/pylance
                basedpyright = {
                    -- It is usually import path such as "os"
                    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. When set to a float
            -- between 0 and 1, it'll be treated as percentage of the width of
            -- the window: math.floor(max_width * vim.api.nvim_win_get_width(0))
            -- Default 60.
            max_width = 60,
        })
    end,
}

use it in nvim-cmp:

require("cmp").setup({
    formatting = {
        format = function(entry, vim_item)
            local highlights_info = require("colorful-menu").cmp_highlights(entry)

            -- highlight_info is nil means we are missing the ts parser, it's
            -- better to fallback to use default `vim_item.abbr`. What this plugin
            -- offers is two fields: `vim_item.abbr_hl_group` and `vim_item.abbr`.
            if highlights_info ~= nil then
                vim_item.abbr_hl_group = highlights_info.highlights
                vim_item.abbr = highlights_info.text
            end

            return vim_item
        end,
    },
})

use it in blink.cmp:

config = function()
    require("blink.cmp").setup({
        completion = {
            menu = {
                draw = {
                    -- We don't need label_description now because label and label_description are already
                    -- combined together in label by colorful-menu.nvim.
                    columns = { { "kind_icon" }, { "label", gap = 1 } },
                    components = {
                        label = {
                            text = function(ctx)
                                return require("colorful-menu").blink_components_text(ctx)
                            end,
                            highlight = function(ctx)
                                return require("colorful-menu").blink_components_highlight(ctx)
                            end,
                        },
                    },
                },
            },
        },
    })
end

If you want to customize a bit more in those options, here is a more granular control approach:

Click to see
config = function()
    require("blink.cmp").setup({
        completion = {
            menu = {
                draw = {
                    -- We don't need label_description now because label and label_description are already
                    -- combined together in label by colorful-menu.nvim.
                    columns = { { "kind_icon" }, { "label", gap = 1 } },
                    components = {
                        label = {
                            width = { fill = true, max = 60 },
                            text = function(ctx)
                                local highlights_info = require("colorful-menu").blink_highlights(ctx)
                                if highlights_info ~= nil then
                                    -- Or you want to add more item to label
                                    return highlights_info.label
                                else
                                    return ctx.label
                                end
                            end,
                            highlight = function(ctx)
                                local highlights = {}
                                local highlights_info = require("colorful-menu").blink_highlights(ctx)
                                if highlights_info ~= nil then
                                    highlights = highlights_info.highlights
                                end
                                for _, idx in ipairs(ctx.label_matched_indices) do
                                    table.insert(highlights, { idx, idx + 1, group = "BlinkCmpLabelMatch" })
                                end
                                -- Do something else
                                return highlights
                            end,
                        },
                    },
                },
            },
        },
    })
end

Custom configuration with lspkind.nvim

You can configure your completion engine (below is for nvim-cmp with both colorful-menu.nvim and lspkind.nvim to get completion menu like those in Screen section.

Click to see
formatting = {
  fields = { "kind", "abbr", "menu" },

  format = function(entry, vim_item)
    local kind = require("lspkind").cmp_format({
        mode = "symbol_text",
    })(entry, vim.deepcopy(vim_item))
    local highlights_info = require("colorful-menu").cmp_highlights(entry)

    -- highlight_info is nil means we are missing the ts parser, it's
    -- better to fallback to use default `vim_item.abbr`. What this plugin
    -- offers is two fields: `vim_item.abbr_hl_group` and `vim_item.abbr`.
    if highlights_info ~= nil then
        vim_item.abbr_hl_group = highlights_info.highlights
        vim_item.abbr = highlights_info.text
    end
    local strings = vim.split(kind.kind, "%s", { trimempty = true })
    vim_item.kind = " " .. (strings[1] or "") .. " "
    vim_item.menu = ""

    return vim_item
  end,
}

Screen

đź’ˇ Note: You may want to set CmpItemAbbrMatch or BlinkCmpLabelMatch to only have bold style (without fg) to achieve a similar effect as the images below.

gopls

before:

image

after:

image

rust-analyzer

before:

image

after:

image

clangd

before:

image

after:

image

lua_ls

before:

image

after:

image

typescript-language-server

before:

image

after:

image

intelephense

Thanks to @pnx

before:

image

after:

image

zls

before:

image

after:

image

roslyn

Thanks to @seblj

before:

image

after:

image

basedpyright

before:

image

after:

image

dartls

before:

image

after:

image

Contributing

Feel free to open issues or submit pull requests if you encounter any bugs or have feature requests.

License

MIT License.

Credit

Zed for the initial idea of colorize.

@David van Munster for the pr which make this plugin possible.

JetBrains for its right-aligned type layout

About

Bring enjoyment to your auto completion.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages