# nvim-highlight-colors: colour swatches inside the Neovim buffer

> nvim-highlight-colors is a Lua plugin that highlights colour literals where you type them, covering hex, rgb, hsl, named colours, ANSI escapes, CSS variables and Tailwind classes, with a completion integration that shows a swatch next to each candidate. Its per-pattern toggles are numerous, and the plugin has no tagged releases.

**brenoprata10/nvim-highlight-colors** — Highlight colors for neovim

- Repository: https://github.com/brenoprata10/nvim-highlight-colors
- Stars: 1,051 · Forks: 69
- Language: Lua
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/brenoprata10-nvim-highlight-colors

## A highlighter for colour literals, not a colour scheme

The plugin's job is narrow and worth stating precisely. It highlights colour values inside the buffer, so a hex string, an rgb function call, a hsl function call or a CSS custom property reference is painted in the colour it actually resolves to.

What it is not is a theme. It does not define your background, your foreground or your syntax palette. It adds inline highlights on top of whatever colourscheme you already run, which means it composes with your existing setup rather than replacing it.

The supported formats are listed in the README: hex, rgb, hsl, CSS variables and Tailwind CSS, plus named colours. The feature list also mentions realtime colour highlighting, so the rendering updates as you type rather than only on buffer reload.

The practical audience is a front end developer who is tired of reading #0f1219 and wondering what it looks like. The same mechanism is useful in a design tokens file, in a theme definition, or anywhere a colour is written as a literal rather than referenced by name.

## Per pattern toggles, most of them on by default

The options table is where most of the configuration surface lives, and it is worth reading before the first install. Each pattern family has its own boolean switch.

```lua
enable_hex = true,
enable_short_hex = true,
enable_rgb = true,
enable_hsl = true,
enable_ansi = true,
enable_xterm256 = true,
enable_xtermTrueColor = true,
enable_hsl_without_function = true,
enable_var_usage = true,
enable_named_colors = true,
enable_tailwind = false,
```

Two entries stand out. enable_tailwind is the only one set to false, so Tailwind classes such as bg-blue-500 are not highlighted until you ask for it, while everything else is on. And enable_named_colors means a bare word like green in any file gets painted, which is the switch most likely to surprise someone who opens a prose file or a log and finds random words coloured.

The ANSI family is more granular than it first appears. There are separate switches for plain ANSI escapes, xterm 256 colours and xterm True Color, and one for hsl written without the hsl() wrapper, as in a CSS custom property declaration of the form --foreground: 0 69% 69%.

## Three render modes and the virtual symbol placement rules

The render option decides how the colour is drawn. The README documents three values, background, foreground and virtual, and the default is background.

```lua
render = 'background',
virtual_symbol = '■',
virtual_symbol_prefix = '',
virtual_symbol_suffix = ' ',
virtual_symbol_position = 'inline',
```

The virtual mode is the more interesting one because it needs its own geometry options. The virtual symbol position accepts inline, eol or eow. The README explains each: inline mimics VS Code style, eol stands for end of column, and eow stands for end of word.

The two suffix options exist because of the position setting, and the README pairs them with explicit recommendations. For eol, set virtual_symbol_suffix to an empty string so the marker sits tight against the value. For eow, set virtual_symbol_prefix to a single space and virtual_symbol_suffix to an empty string so the marker does not overlap the following word.

Getting this wrong is the difference between a tidy column of swatches and a line that looks broken, and the defaults are tuned for the inline case rather than the other two.

## LSP documentColor support, and where it comes from

The plugin can source a colour from a language server rather than from a literal in the text. The README says this works with any LSP that supports textDocument/documentColor, and names tailwindcss and csslsp as the examples.

This is the mechanism behind the completion integrations, and it is worth understanding the distinction. The background and foreground highlighters work on text you can see. The LSP path works on a completion item's documentation, which is where a server can report the resolved colour of a variable that is defined elsewhere.

That is why the README frames LSP support as a feature rather than a detail. A CSS custom property that resolves to a theme colour is a different problem from a literal, and the documentColor capability is what lets a completion menu show you the resolved swatch for an indirect reference.

The limitation follows from the same place. If your language server does not implement textDocument/documentColor, the LSP route simply has no data to work with, and the plugin falls back to whatever it can parse from the text itself.

## Hooking the swatch into nvim-cmp and blink.cmp

The plugin exposes a format function that completion plugins can call, and the README gives two ways to use it with nvim-cmp. The simple version replaces the formatter outright.

```lua
require("cmp").setup({
        ... other configs
        formatting = {
                format = require("nvim-highlight-colors").format
        }
})
```

The second version composes it with your own logic, calling the plugin's format function and passing the result through. The README is candid about a compatibility wrinkle here: the out of the box format function does not necessarily play nicely with lspkind and potentially other formatters, and may require manual intervention. The lspkind example shows the shape of the fix, taking the plugin's abbr and abbr_hl_group and overwriting the kind and kind_hl_group fields.

```lua
local color_item = require("nvim-highlight-colors").format(entry, { kind = item.kind })
item = require("lspkind").cmp_format({
        -- any lspkind format settings here
})(entry, item)
if color_item.abbr_hl_group then
        item.kind_hl_group = color_item.abbr_hl_group
        item.kind = color_item.abbr
end
```

The blink.cmp integration is different in kind. Rather than formatting a completion item, it replaces the kind icon with a text function and a highlight function, each of which checks whether the source is LSP and only then derives a colour from the item documentation. The result is that a CSS variable completion entry shows its swatch in place of the usual kind icon.

## Excluding files, buffers and custom labels

Highlighting everything by default is only sensible if you can turn it off in the places it does not belong. The options table provides three exclusion mechanisms, and they work at different levels.

```lua
exclude_filetypes = {},
exclude_buftypes = {},
exclude_buffer = function(bufnr) end
```

Filetypes and buftypes are lists, with the README giving 'text' as the example buftype to exclude. exclude_buffer is a function receiving the buffer number and returning a value, with the documented example comparing the file size of the buffer against one megabyte using vim.fn.getfsize and vim.api.nvim_buf_get_name. The default implementation returns nothing, so nothing is excluded until you write your own predicate.

There is also a custom_colors option for colours the plugin cannot infer from the text. Each entry has a label and a colour, and the README explains the constraint clearly: the label must be properly escaped with the percent character to satisfy string.gmatch, with a pointer to the string.gmatch help topic. The example uses labels like %-%-theme%-primary%-color, which is the CSS custom property double dash written in a pattern-friendly form.

## A small Lua plugin with no tagged releases

The repository layout is minimal, with a lua/ directory holding the plugin code, a LICENSE, the README, a.github directory, and a testing.txt file at the root. The README carries a badge linking to a Dotfyle plugin page, which is where a lot of Neovim users look for configuration snippets.

Two things about the project's shape are worth stating plainly. The repository has no GitHub releases at all, so there is no versioned artefact to pin, and the last push was on 2026-05-05. For a plugin whose entire value is the visual output, tracking upstream means tracking a branch rather than a tag, and a plugin manager that tracks a commit has no upgrade path to a numbered release.

The licence is MIT, which is permissive but still requires keeping the copyright and licence notice when the code is reused.

The options block in the README is also the de facto documentation. There is no separate manual, so the reference for a new option is the README table and the plugin's own help, and the README points at a commands section for the user commands the plugin registers.

## Conclusion

nvim-highlight-colors fits a Neovim user who writes CSS, Tailwind or anything else with colour literals and wants to see the value rather than read it, especially if you already run nvim-cmp or blink.cmp and want colour swatches in the completion menu. It is the wrong tool if you want a curated theme, since it changes no colours of its own and only paints inline swatches, and it is the wrong tool if you dislike a buffer covered in highlight groups, since each match creates one. Before enabling anything beyond the defaults, note that enable_tailwind ships as false while every other pattern is on by default, so the plugin highlights more aggressively than most people expect on a first install.

## FAQ

### How do I install nvim-highlight-colors in Neovim?

Add 'brenoprata10/nvim-highlight-colors' to your plugin manager, then enable true colour with vim.opt.termguicolors = true and call require('nvim-highlight-colors').setup({}) in your configuration.

### Which colour formats does nvim-highlight-colors support?

The README lists hex, rgb, hsl, CSS variables and Tailwind CSS in the feature list, and the options add named colours, short hex, ANSI escapes, xterm 256 and xterm True Color, plus hsl written without the function wrapper.

### Why is Tailwind highlighting not working by default?

The enable_tailwind option is set to false in the documented options block, while every other pattern switch is on. Set it to true to highlight classes such as bg-blue-500.

### How do I show colour swatches in nvim-cmp completions?

Pass the plugin's format function to the completion plugin, either directly as formatting.format or inside your own function, and if you also use lspkind, copy the abbr and abbr_hl_group values onto the item's kind and kind_hl_group fields as the README example shows.

### Can I stop nvim-highlight-colors from highlighting a buffer?

Yes. The options accept exclude_filetypes and exclude_buftypes lists, and exclude_buffer, a function that receives the buffer number and returns a value when the buffer should be skipped.

## Sources

- [brenoprata10/nvim-highlight-colors on GitHub](https://github.com/brenoprata10/nvim-highlight-colors)
- [Issues](https://github.com/brenoprata10/nvim-highlight-colors/issues)
- [License: MIT](https://github.com/brenoprata10/nvim-highlight-colors/blob/main/LICENSE)
- [README](https://github.com/brenoprata10/nvim-highlight-colors/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/brenoprata10-nvim-highlight-colors
