A Material You colorscheme bridge for Neovim. Built as a drop-in solution that maps matugen's colors straight to Neovim highlight groups through a semantic palette, with minimal setup required
https://github.com/user-attachments/assets/5b9e40a9-a8e1-4b9b-badd-f4b667d55f5e
Copy nvim-colors.json to your matugen templates folder
config.toml[templates.neovim]
input_path = "~/.config/matugen/templates/nvim-colors.json"
output_path = "~/.cache/matugen/nvim-colors.json"
post_hook = "pkill -SIGUSR1 nvim"
lazy.nvim{
"Senal-D-A-Gunaratna/matugen.nvim",
lazy = false,
priority = 1000,
opts = {
palette_path = "~/.cache/matugen/nvim-colors.json",
-- load_theme = false,
-- custom_templates = "~/.config/nvim/matugen-templates",
},
},
By default, the plugin automatically loads the generated palette and sets
itself as your active colorscheme — no extra vim.cmd.colorscheme(...) call
needed
Set load_theme = false if you'd rather manage the colorscheme yourself and
don't want the plugin to apply it automatically
Terminal opacity can be achieved on most other DEs/WMs too (window rules, compositor configs, etc) — this section covers the Hyprland-specific approach
For transparency in Neovim that doesn't affect your regular terminal, use hyprfade.nvim. Unlike a static Hyprland window rule, it toggles opacity only while Neovim is focused — and it works even when Neovim's window title doesn't update in time for a class/title match (e.g. launching from Yazi)
Or set a static rule yourself:
hl.window_rule({
match = { class = "kitty", title = "nvim" },
opacity = "0.7",
})
The post_hook in config.toml reloads Neovim automatically on every
matugen run. To trigger it manually:
pkill -SIGUSR1 nvim
or, from inside Neovim:
:MatugenReload
The plugin always ends up with a usable theme, and tells you when it isn't rendering the palette you expected:
custom_templates fails to load — the built-in template of
the same name is used and the whole theme renders from the fallback colors,
because a customization you believe is active but isn't is worse than an
obvious one. Fix the file and run :MatugenReload:checkhealth matugen lists any failures and which palette is in use. See
Creating Custom Templates for the full rules
:checkhealth matugen
Verifies your config, template parsing, active templates, and load status
Built-in templates live in lua/matugen/templates:
Custom templates directory — set custom_templates to a directory of
your own templates, layered on top of the built-in ones. Built-in
templates are applied first and yours last, so a custom template only
needs to set the highlight groups you want to change:
opts = {
custom_templates = "~/.config/nvim/matugen-templates",
palette_path = "~/.cache/matugen/nvim-colors.json",
}
Nothing is copied out of the plugin, so updates never overwrite your
work. If the directory doesn't exist yet, it's created empty and
you're notified. A file that matches a built-in template's name replaces
it; the same name with a blank file disables it. A file that fails to
load is reported as an error and ignored, so the built-in stays rather
than silently losing its highlights — fix it and run :MatugenReload.
Only the top level of the directory is scanned.
Add a template by dropping a Lua file into that directory, then run
:MatugenReload.
Tweaking colors doesn't require touching any plugin code. Edit your
nvim-colors.json template directly — remap a semantic
key to a different matugen color role (e.g. point cursor_block at
tertiary instead of primary), adjust the alpha suffix on
selection_bg/word_highlight, or swap in a hardcoded hex value. Run
matugen again (or :MatugenReload) to see the change
Every highlight group comes from one semantic palette in
lua/matugen/palette.lua, so adding a new plugin or UI component stays
consistent
Cursor theming is done by shape, not mode:
| Shape | Cursors | Palette key |
|---|---|---|
| Block | Cursor, smCursor, TermCursor |
cursor_block |
| Beam | iCursor, lCursor |
cursor_beam |
| Underline | rCursor, oCursor |
cursor_underline |
Block cursor colors work in any terminal. Per-shape colors need a terminal that honors cursor coloring (kitty, wezterm, foot); terminals that don't (GNOME Terminal, Alacritty) just get a plain cursor
Foreground pairing follows contrast needs: block cursors use high-contrast
on_primary, while beam/underline cursors use the softer on_surface.
Unfocused terminal windows get the dimmed TermCursorNC, matching the rest
of the *NC groups
See Creating Custom Templates to extend it
PRs welcome — new plugin support, bug fixes, anything that makes this better
If you find this useful, consider giving it a ⭐ — it helps others discover the project
MIT