Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

matugen-mix.nvim

A tiny Neovim helper for making an existing colorscheme slightly harmonize with a matugen palette.

It does not replace your colorscheme.
It does not generate a full theme.
It does not try to become a universal design system, because that is how small weekend ideas become architectural paperwork.

It simply takes colors from matugen, mixes them gently into selected colorscheme colors, and lets Neovim look a little less like it was excluded from the rest of the desktop.

Why

My desktop theme is generated from the current wallpaper using matugen.

That means the wallpaper influences things like:

  • Hyprland
  • Waybar
  • Rofi
  • terminal colors
  • possibly other infected parts of the environment

Neovim, however, usually uses a fixed colorscheme. In my case that is mostly tokyonight-moon.

The problem is not that TokyoNight is ugly. It is not. We are not monsters.

The problem is that a fixed Neovim background can appear dull, flat, or slightly disconnected when it sits next to a wallpaper-derived desktop palette.

This is mostly a perception issue: colors change their apparent character depending on nearby colors. A background that looks good alone can look desaturated or dead when placed against a glowing blue/pink/purple wallpaper.

So the idea is:

keep the original colorscheme identity
+
borrow a very small amount of matugen mood
=
less visual disagreement

In other words:

TokyoNight Moon, but it knows what wallpaper it lives with.

What it does

matugen-mix.nvim reads a generated Lua palette file, for example:

~/.config/nvim/lua/generated/matugen-colors.lua

Then it mixes selected colorscheme values with selected matugen colors.

For example:

TokyoNight bg + 5% matugen primary = slightly warmer/lifted bg

This is meant to be subtle.
If it screams, it is wrong.
If it quietly stops annoying you, it is working.

What it does not do

This plugin does not:

  • replace your colorscheme
  • generate a complete Neovim theme
  • manage wallpapers
  • run matugen
  • configure Hyprland, Waybar, Rofi, or your tea kettle
  • promise taste, because computers are already bold enough

It only mixes colors.

Directory

My local development path:

~/Development/lua/NeoVim/matugen-mix.nvim

Suggested structure:

matugen-mix.nvim/
├── README.md
└── lua/
    └── matugen-mix/
        ├── init.lua
        └── color.lua

Matugen setup

First, create a template for Neovim colors.

Example path:

~/.config/matugen/templates/nvim-colors.lua

Template:

-- Generated by matugen.
-- Do not edit by hand unless you enjoy losing small wars against automation.

return {
  source = {
    image = "{{ image }}",
  },

  colors = {
    background = "{{ colors.background.default.hex }}",
    surface = "{{ colors.surface.default.hex }}",
    surface_variant = "{{ colors.surface_variant.default.hex }}",

    primary = "{{ colors.primary.default.hex }}",
    secondary = "{{ colors.secondary.default.hex }}",
    tertiary = "{{ colors.tertiary.default.hex }}",

    on_background = "{{ colors.on_background.default.hex }}",
    on_surface = "{{ colors.on_surface.default.hex }}",

    error = "{{ colors.error.default.hex }}",
  },
}

Then add the template to matugen.

Example:

[templates.nvim]
input_path = "~/.config/matugen/templates/nvim-colors.lua"
output_path = "~/.config/nvim/lua/generated/matugen-colors.lua"

After running matugen, Neovim should have a generated module like this:

return {
  source = {
    image = "~/.config/backgrounds/woman_reading_pinker.png",
  },

  colors = {
    background = "#161217",
    surface = "#161217",
    surface_variant = "#4c444c",

    primary = "#e6b6f1",
    secondary = "#d5c0d7",
    tertiary = "#f5b7b3",

    on_background = "#eae0e7",
    on_surface = "#eae0e7",

    error = "#ffb4ab",
  },
}

Test inside Neovim:

:lua print(vim.inspect(require("generated.matugen-colors")))

If that prints a table, the infection route is open.

Installation

Using lazy.nvim with a local plugin directory:

{
  dir = "~/Development/lua/NeoVim/matugen-mix.nvim",
  name = "matugen-mix.nvim",
}

Or as a dependency of the colorscheme:

{
  "folke/tokyonight.nvim",
  dependencies = {
    {
      dir = "~/Development/lua/NeoVim/matugen-mix.nvim",
      name = "matugen-mix.nvim",
    },
  },
}

Usage with TokyoNight

Example TokyoNight configuration:

return {
  {
    "folke/tokyonight.nvim",

    dependencies = {
      {
        dir = "~/Development/lua/NeoVim/matugen-mix.nvim",
        name = "matugen-mix.nvim",
      },
    },

    opts = function(_, opts)
      opts = opts or {}

      local matugen_mix = require("matugen-mix")

      matugen_mix.setup({
        enabled = true,

        colors_module = "generated.matugen-colors",

        palette = {
          bg = 0.05,
          bg_dark = 0.04,
          bg_float = 0.06,
          bg_sidebar = 0.06,
        },
      })

      opts.style = "moon"

      opts.on_colors = function(colors)
        matugen_mix.apply_tokyonight(colors, {
          accent = "primary",
        })
      end

      opts.on_highlights = function(h, c)
        h.WinSeparator = { fg = c.blue7, bg = "NONE" }
        h.VertSplit = { link = "WinSeparator" }

        -- Your other highlight tweaks can live here.
        -- Syntax styling belongs in on_highlights.
        -- Palette/background mutation belongs in on_colors.
      end

      return opts
    end,
  },
}

The important distinction:

opts.on_colors = function(colors)
  -- change base palette colors
end

Use this for things like:

  • bg
  • bg_dark
  • bg_float
  • bg_sidebar

And:

opts.on_highlights = function(highlights, colors)
  -- change final highlight groups
end

Use this for things like:

  • Treesitter groups
  • WinSeparator
  • NormalFloat
  • custom plugin highlights

Tiny rule:

color ingredients go in on_colors
finished decorations go in on_highlights

Toggle support

The plugin provides:

:MatugenMixEnable
:MatugenMixDisable
:MatugenMixToggle

The toggle is session-local by default.

That means after restarting Neovim, the plugin uses the configured value:

enabled = true

This is intentional. Persistent state can come later, when this tiny color helper inevitably starts pretending to be infrastructure.

Snacks toggle integration

If using snacks.nvim, add a toggle mapping.

Example:

return {
  {
    "folke/snacks.nvim",
    enabled = true,

    opts = {
      image = {
        enabled = true,
        doc = {
          inline = false,
          float = true,
          max_width = 40,
          max_height = 20,
        },
      },

      explorer = { trash = false },

      statuscolumn = {
        enabled = true,
      },
    },

    init = function()
      vim.api.nvim_create_autocmd("User", {
        pattern = "VeryLazy",
        callback = function()
          local Snacks = require("snacks")

          Snacks.toggle({
            name = "Matugen Mix",
            get = function()
              return require("matugen-mix").is_enabled()
            end,
            set = function(state)
              local matugen_mix = require("matugen-mix")

              if state then
                matugen_mix.enable()
              else
                matugen_mix.disable()
              end
            end,
          }):map("<leader>um")
        end,
      })
    end,
  },
}

Suggested keymap:

<leader>um

Meaning:

u = UI / toggles
m = Matugen Mix

Or, less officially:

m = mood infection

Configuration

Default-ish setup:

require("matugen-mix").setup({
  enabled = true,

  colors_module = "generated.matugen-colors",

  fallback_accent = "#7aa2f7",

  default_amount = 0.05,

  palette = {
    bg = 0.05,
    bg_dark = 0.04,
    bg_float = 0.06,
    bg_sidebar = 0.06,
  },
})

enabled

Whether the mix is active.

enabled = true

When disabled, apply_tokyonight() does nothing and the colorscheme loads normally.

colors_module

The Lua module generated by matugen.

colors_module = "generated.matugen-colors"

This expects a file at:

~/.config/nvim/lua/generated/matugen-colors.lua

Which can be required as:

require("generated.matugen-colors")

fallback_accent

Used if the generated matugen file cannot be loaded.

fallback_accent = "#7aa2f7"

Because failing gracefully is better than exploding during startup like a tiny Lua opera.

default_amount

Default mix amount.

default_amount = 0.05

This means 5%.

Recommended range:

0.03 - 0.08

Above that, the theme may stop looking gently adjusted and start looking like it has joined a neon monastery.

palette

Defines which colorscheme fields should be mixed and by how much.

palette = {
  bg = 0.05,
  bg_dark = 0.04,
  bg_float = 0.06,
  bg_sidebar = 0.06,
}

For TokyoNight, useful keys include:

bg
bg_dark
bg_float
bg_sidebar

Choosing an accent

Example:

matugen_mix.apply_tokyonight(colors, {
  accent = "primary",
})

Common options from the generated palette:

primary
secondary
tertiary
background
surface
surface_variant

For the current woman_reading_pinker.png wallpaper, example values were:

primary = "#e6b6f1"
secondary = "#d5c0d7"
tertiary = "#f5b7b3"

Suggested behavior:

primary   = stronger pink/purple influence
secondary = softer, safer influence
tertiary  = warmer pink/salmon influence

When in doubt, start with:

accent = "primary"

and small values:

bg = 0.05

If it becomes too pink:

accent = "secondary"

If it still looks dead:

bg = 0.07

If it looks like a nightclub for haunted TypeScript:

bg = 0.03

Acknowledgements

This plugin exists mostly as a small bridge between tools that already do the hard work.

Special thanks to folke for TokyoNight and Snacks.nvim.

TokyoNight provides the actual colorscheme foundation here — this plugin only nudges a few colors so the theme feels more at home inside a wallpaper-driven desktop. Snacks.nvim also makes the optional toggle integration pleasantly easy, which is suspiciously civilized for Neovim.

Thanks also to the people behind matugen, which does the real color extraction magic. matugen-mix.nvim does not try to replace it, compete with it, or pretend to understand color theory better than it does. It simply reads the palette matugen generates and lets that palette gently influence Neovim.

In short:

matugen finds the mood
TokyoNight provides the room
Snacks gives us a switch
this plugin just opens the window a little

Debugging

Check that the generated palette can be loaded:

:lua print(vim.inspect(require("generated.matugen-colors")))

Check the current primary color:

:lua print(require("matugen-mix").get_color("primary"))

Check a manual mix:

:lua print(require("matugen-mix").mix("#222436", "primary", 0.05))

Toggle on/off:

:MatugenMixToggle

Check whether it is enabled:

:lua print(require("matugen-mix").is_enabled())

Recommended workflow

  1. Change wallpaper.
  2. Run matugen.
  3. Start or reload Neovim.
  4. Toggle Matugen Mix on/off.
  5. Adjust mix amount if needed.
  6. Stop before inventing a full theme engine.

The last step is important and will probably be ignored.

Design principle

The plugin should stay boring.

Good boring.

The kind of boring where it does one thing, does not surprise you, and does not turn into a config hydra.

Core idea:

read generated colors
mix carefully
allow toggle
get out of the way

Status

Personal local plugin.

Working target:

Arch Linux + Hyprland + matugen + TokyoNight Moon + Snacks.nvim

Used mainly to make Neovim visually harmonize with a wallpaper-driven desktop without abandoning the original colorscheme.

The matugen virus spreads, but politely.

About

Neovim plugin for subtly blending matugen-generated colors into existing colorschemes like TokyoNight.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages