mini.hues 配置化色彩方案生成器:用两个基础色生成整套 Neovim 主题
【免费下载链接】mini.nvimLibrary of 45+ independent Lua modules improving Neovim experience with minimal effort项目地址: https://gitcode.com/GitHub_Trending/mi/mini.nvim
本文围绕 mini.nvim 库中的 mini.hues 模块展开,讲解如何通过background与foreground两个必填基础色,自动推导出一套协调的 Neovim 配色方案。读完本文,你将掌握setup()的全部配置项、Oklch 色彩空间下的调色板生成原理、四大季节内置主题与randomhue随机主题的使用方式,以及如何借助make_palette()/apply_palette()等公开 API 对主题进行二次定制。
mini.hues 是什么
mini.hues 是 mini.nvim 库中负责"生成可配置配色方案"的独立 Lua 模块。它的核心设计思路非常简单:用户只需指定背景色与前景色两个基础色,其余所有颜色(语法高亮、UI 元素、诊断、Tree-sitter、插件高亮等)都由模块自动计算,并尽量让它们之间保持足够的感知差异(perceptually different)。
模块将生成的高亮组写入全局表MiniHues,可通过:lua MiniHues.*手动访问。需要特别注意的是,调用setup()本身并不会注册一个:colorscheme,它只是创建一套协调的高亮组;要形成真正的配色方案,还需要按 创建自己的配色方案 一节的操作封装成 colors 目录下的脚本。
快速开始:两个必填字段
mini.hues 的启用方式是require('mini.hues').setup({...}),其中background与foreground为必填字段(均为'#rrggbb'十六进制字符串)。源码 hues.lua 中明确校验了这一点:
if config.background == nil or config.foreground == nil then H.error('`setup()` needs both `background` and `foreground`.') end最简配置示例(深青色背景搭配浅色前景):
require('mini.hues').setup({ background = '#11262d', foreground = '#c0c8cc', })此外,background与foreground必须具有相反的明度(一深一浅),否则会抛出'backgroundandforegroundshould have opposite lightness.'错误,相关校验见 hues.lua。
该模块没有运行时选项,因此设置vim.b.minihues_config不会产生任何效果。
完整配置说明
setup()接受的配置表结构与默认值如下(源自 hues.lua 与 readme 的 Default config 一节):
{ -- REQUIRED 基础色,'#rrggbb' 十六进制字符串 background = nil, foreground = nil, -- 非基础色使用的色相数量(0 到 8) n_hues = 8, -- 饱和度:'low' | 'lowmedium' | 'medium' | 'mediumhigh' | 'high' saturation = 'medium', -- 强调色,用于部分选中 UI 元素。可选值: -- 'bg', 'fg', 'red', 'orange', 'yellow', 'green', 'cyan', 'azure', 'blue', 'purple' accent = 'bg', -- 插件集成。`default = false` 可关闭全部集成,也可按插件单独设置 plugins = { default = true }, -- 是否根据相关事件自动调整部分高亮组 autoadjust = true, }各配置项的作用
| 配置项 | 取值范围 | 默认值 | 说明 |
|---|---|---|---|
background/foreground | '#rrggbb' | 无(必填) | 调色板生成的唯一输入基础色,二者明度必须相反 |
n_hues | 0~8 整数 | 8 | 非基础颜色使用的色相数量。色相在色环上等距分布,并尽量远离两个基础色的色相 |
saturation | 'low'/'lowmedium'/'medium'/'mediumhigh'/'high' | 'medium' | 彩色文本的饱和度等级,对应 Oklch 色彩空间中的 Chroma 值 |
accent | 'bg'、'fg'或八种非基础色名 | 'bg' | 用于Search、FloatBorder、Title、CursorLineNr等选中 UI 元素的强调色 |
plugins | 表,键为插件名或default | { default = true } | 控制是否为各插件创建高亮组 |
autoadjust | 布尔值 | true | 是否根据fillchars、pumborder等选项自动调整MsgSeparator、Pmenu |
saturation 与 chroma 的对应关系
在 make_palette 的实现中,饱和度等级被直接映射为 Oklch 的 Chroma 数值:
local chroma = ({ low = 4, lowmedium = 6, medium = 8, mediumhigh = 12, high = 16 })[saturation]也就是说low对应 Chroma 4,high对应 Chroma 16,等级越高,非基础色越鲜艳。
plugins 与 autoadjust 细节
- 插件集成:
config.plugins决定了为哪些受支持插件创建高亮组。规则为:若某个插件名(见下文插件列表)有对应条目则使用该条目,否则回退到config.plugins.default。限制集成数量可以减少启动时间。例如只加载 mini.nvim 自身集成:
require('mini.hues').setup({ background = '#11262d', foreground = '#c0c8cc', plugins = { default = false, ['nvim-mini/mini.nvim'] = true, }, })- 自动调整(
autoadjust = true时生效,实现见 hues.lua):MsgSeparator根据'fillchars'中的msgsep标志调整:若为空白则高亮背景,否则高亮前景;Pmenu(补全菜单)根据'pumborder'值调整(Neovim 0.12+):带边框时与浮动窗口一致(但边框无强调色前景),否则与CursorLine一致,从而让补全菜单与普通浮动窗口区分开来。
配置示例:从基础色到风格微调
readme 与 doc/mini-hues.txt 提供了大量可直接套用的配置(使用时只保留一行setup调用即可):
local setup = require('mini.hues').setup -- 选择背景与前景色(按色调区分) setup({ background = '#2f1c22', foreground = '#cdc4c6' }) -- red setup({ background = '#2f1e16', foreground = '#cdc5c1' }) -- orange setup({ background = '#282211', foreground = '#c9c6c0' }) -- yellow setup({ background = '#1c2617', foreground = '#c4c8c2' }) -- green setup({ background = '#112723', foreground = '#c0c9c7' }) -- cyan setup({ background = '#11262d', foreground = '#c0c8cc' }) -- azure setup({ background = '#1d2231', foreground = '#c4c6cd' }) -- blue setup({ background = '#281e2c', foreground = '#c9c5cb' }) -- purple -- 控制非基础色相数量 setup({ background = '#11262d', foreground = '#c0c8cc', n_hues = 6 }) setup({ background = '#11262d', foreground = '#c0c8cc', n_hues = 4 }) setup({ background = '#11262d', foreground = '#c0c8cc', n_hues = 2 }) setup({ background = '#11262d', foreground = '#c0c8cc', n_hues = 0 }) -- 控制文本饱和度 setup({ background = '#11262d', foreground = '#c0c8cc', saturation = 'low' }) setup({ background = '#11262d', foreground = '#c0c8cc', saturation = 'lowmedium' }) setup({ background = '#11262d', foreground = '#c0c8cc', saturation = 'medium' }) setup({ background = '#11262d', foreground = '#c0c8cc', saturation = 'mediumhigh' }) setup({ background = '#11262d', foreground = '#c0c8cc', saturation = 'high' }) -- 选择强调色 setup({ background = '#11262d', foreground = '#c0c8cc', accent = 'bg' }) setup({ background = '#11262d', foreground = '#c0c8cc', accent = 'red' }) setup({ background = '#11262d', foreground = '#c0c8cc', accent = 'yellow' }) setup({ background = '#11262d', foreground = '#c0c8cc', accent = 'cyan' }) setup({ background = '#11262d', foreground = '#c0c8cc', accent = 'blue' })调色板生成原理:Oklch 色彩空间
mini.hues 的调色板生成(MiniHues.make_palette())完全在Oklch色彩空间中完成。Oklch 用三个数值描述颜色:
- 明度 Lightness(l):0(黑)到 100(白);
- 彩度 Chroma(c):正值,越大越鲜艳,0 为灰色;
- 色相 Hue(h):0~360 的周期值,对应色环上的"本色"。
模块内部的十六进制与 Oklch 转换、gamut clipping 等底层能力依赖同库的 mini.colors,相关色空间说明见 doc/mini-colors.txt。
算法流程概述
依据 hues.lua 的文档注释,make_palette()的生成流程如下:
- 提取基础色通道:取出背景色与前景色的明度、彩度、色相;
- 生成参考明度:
- 背景边界:取 0 或 100 中更接近背景明度者;
- 前景边界:与背景边界不同的一端(0 或 100 的另一者);
- 中间值:背景与前景明度的算术平均值;
- 计算底色明度阶梯:通过改变背景色的明度生成
bg_edge/bg_edge2(靠近边界)与bg_mid/bg_mid2(靠近中间)两组明暗变体,前景同理; - 确定彩度:依据
config.saturation选取非基础色的 Chroma; - 生成非基础色色相:
- 在色环上拟合一个含
n_hues个等距点的圆形网格,使其尽量远离背景与前景色相,保证非基础色与基础色差异最大化。例如背景色相 0、前景色相 180、n_hues = 2时,网格为{ 90, 270 }; - 对 8 个参考色相(红、橙、黄、绿、青、蓝、紫等)分别取网格中最近的值,从而即使色相数量减少,仍能沿用"红色""绿色"等同一套术语;
- 在色环上拟合一个含
- 输出两套明度的非基础色:每个色相都生成前景明度与背景明度(
_bg后缀)两个变体; - 计算强调色:基于
config.accent生成accent与accent_bg两个变体。
输出调色板结构
make_palette()返回的调色板表结构如下(字段含义详见 hues.lua):
bg/fg:传入的基础色;bg_edge/bg_edge2/bg_mid/bg_mid2:背景色的明度变体(fg_edge/fg_edge2/fg_mid/fg_mid2同理);red、orange、yellow、green、cyan、azure、blue、purple:前景明度的非基础色;带_bg后缀者为背景明度变体;accent/accent_bg:前景/背景明度的强调色。
需要说明的是,部分生成颜色无法用'#rrggbb'精确表示,此时会执行 gamut clipping(在不改变色相的前提下以最优方式降低明度与彩度)来得到可表示的十六进制值;且并非所有颜色都会被高亮组使用,部分字段仅为完整性而保留。
公开 API:setup、make_palette、apply_palette、get_palette、gen_random_base_colors
mini.hues 对外暴露五个主要函数(均可在MiniHues全局表中访问):
MiniHues.setup(config)
模块入口,等价于make_palette()与apply_palette()的组合(见 hues.lua),调用后会导出全局表MiniHues、校验并应用配置。
MiniHues.make_palette(config)
仅计算调色板而不应用,接受与setup()相同的配置结构(必须有background、foreground)。可用于预览或二次加工调色板。
MiniHues.apply_palette(palette, plugins, opts)
根据给定调色板创建高亮组与终端色。适合"微调配色板后再应用"的场景:
local palette = require('mini.hues').make_palette({ background = '#11262d', foreground = '#c0c8cc', }) palette.cyan = '#76e0a6' palette.cyan_bg = '#004629' require('mini.hues').apply_palette(palette)plugins(默认取MiniHues.config.plugins)决定为哪些插件建组;opts.autoadjust(默认取MiniHues.config.autoadjust)控制自动调整。实现见 hues.lua。此外,apply_palette()还会根据背景明度推导vim.g.terminal_color_0至terminal_color_15共 16 个终端色(见 hues.lua)。
MiniHues.get_palette()
返回最近一次通过apply_palette()应用(含setup()内部调用)的调色板副本,实现见 hues.lua。
MiniHues.gen_random_base_colors(opts)
基于随机色相与启发式明度/彩度生成一组基础色,返回{ background = ..., foreground = ... }。它尊重'background'选项:
- 深色背景:
bg明度 15、彩度 3;fg明度 80、彩度 1; - 浅色背景:
bg明度 90、彩度 1;fg明度 20、彩度 1。
opts.gen_hue可传入一个返回色相数值的函数来限制生成范围(默认math.random(0, 359)),见 hues.lua。若在启动阶段调用,建议先执行math.randomseed(vim.loop.hrtime())以保证随机性:
local hues = require('mini.hues') math.randomseed(vim.loop.hrtime()) hues.setup(hues.gen_random_base_colors())也可以借助 mini.colors 自行复刻类似逻辑,例如固定明度、只随机色相:
local convert = require('mini.colors').convert local hue = math.random(0, 359) return { background = convert({ l = 15, c = 3, h = hue }, 'hex'), foreground = convert({ l = 80, c = 1, h = hue }, 'hex'), }内置配色方案
mini.hues 附带多个现成配色方案,文件位于仓库 colors 目录。
四季主题
- miniwinter:"icy winter" 寒冬色调,azure(天蓝)背景。实现见 colors/miniwinter.lua,它按
'background'深/浅分别内置了 Oklch 参数推导出的完整调色板,再调用apply_palette()并设置vim.g.colors_name = 'miniwinter'; - minispring:"blooming spring" 春意色调,绿色背景(colors/minispring.lua);
- minisummer:"hot summer" 盛夏色调,棕/黄背景(colors/minisummer.lua);
- miniautumn:"cooling autumn" 秋凉色调,紫色背景(colors/miniautumn.lua)。
randomhue 随机主题
randomhue使用随机生成的同色相背景与前景,每次执行:colorscheme randomhue都会得到一组新的(随机但经过仔细挑选的)颜色。其本质是MiniHues.setup()与MiniHues.gen_random_base_colors()的组合,并对'background'做了微调(见 doc/mini-hues.txt)。
仓库 colors/randomhue.lua 的实现展示了完整流程:
local hues = require('mini.hues') -- 初始化随机种子(否则启动阶段不随机) math.randomseed(vim.loop.hrtime()) local base_colors = hues.gen_random_base_colors() hues.setup({ background = base_colors.background, foreground = base_colors.foreground, n_hues = 8, saturation = vim.o.background == 'dark' and 'medium' or 'high', accent = 'bg', }) vim.g.colors_name = 'randomhue'直接以常规:colorscheme方式激活即可。如需查看当前生效配置,可执行:
:lua print(vim.inspect(MiniHues.config))如何创建自己的配色方案
依据 doc/mini-hues.txt 的说明,创建自定义主题只需两步:
- 在任意
'runtimepath'可达的 "colors" 目录(通常是 Neovim 配置目录下的 colors 文件夹)中新建myscheme.lua(文件名即主题名); - 在文件中先调用
require('mini.hues').setup()传入你的调色板,然后设置vim.g.colors_name = 'myscheme'。
关于 cterm 颜色
为保持实现简洁,mini.hues不定义 cterm 颜色,仅依赖'termguicolors'(若终端模拟器支持 24 位色,Neovim 通常会自动启用)。若终端无法支持真彩色,可改用 mini.colors 的MiniColors.colorscheme:add_cterm_attributes()定义支持 16 色的自定义主题。
受支持的插件高亮组
mini.hues 会为内置 UI、语法、LSP、诊断、Tree-sitter、LSP semantic tokens 以及以下插件创建高亮组(或经过验证确认其默认高亮可正常工作):
- mini.nvim 全家模块(
MiniAnimate*、MiniClue*、MiniFiles*、MiniStatusline*、MiniTabline*等,见 hues.lua) - bufferline.nvim、hydra.nvim、beacon.nvim、lazy.nvim、noice.nvim、snacks.nvim、todo-comments.nvim、trouble.nvim、which-key.nvim
- leap.nvim、dashboard-nvim、lspsaga.nvim、rainbow-delimiters.nvim、nvim-cmp、fzf-lua、vim-sneak
- nvim-bqf、nvim-ufo、gitsigns.nvim、indent-blankline.nvim、render-markdown.nvim、coc.nvim、neogit、lualine.nvim
- neo-tree.nvim、telescope.nvim、nvim-tree.lua、helpview.nvim、markview.nvim、hop.nvim、nvim-dap-ui、nvim-notify、pounce.nvim、barbar.nvim、blink.cmp、aerial.nvim、mason.nvim
每个插件集成块均由if has_integration('<插件名>')条件包裹(如 hues.lua 的 bufferline 部分),因此通过config.plugins即可精准控制。
安装方式
mini.hues 可随 mini.nvim 全库安装(推荐),也可作为独立 Git 仓库安装。可选main分支(默认,含最新开发版,改动处于 beta 阶段)或stable分支(仅在发布时更新,代码经过main分支公测)。以下为常见安装方式(任选其一)。
使用 vim.pack(Neovim 0.12+),独立安装主分支:
vim.pack.add({ 'https://github.com/nvim-mini/mini.hues' })stable 分支:
vim.pack.add({ { src = 'https://github.com/nvim-mini/mini.hues', version = 'stable' }, })使用 mini.deps(Neovim 0.12 之前),主分支:
add('nvim-mini/mini.hues')stable 分支:
add({ source = 'nvim-mini/mini.hues', checkout = 'stable' })使用 lazy.nvim,主分支:
{ 'nvim-mini/mini.hues', version = false },stable 分支:
{ 'nvim-mini/mini.hues', version = '*' },安装完成后务必调用带background与foreground字段的require('mini.hues').setup()才会生效。若在 Windows 上遇到路径过长错误(error: unable to create file ...: Filename too long),可执行git config --system core.longpaths true后重装,或将插件安装到路径更短的位置。
测试与验证
仓库 tests/test_hues.lua 覆盖了模块的核心行为:校验setup()后_G.MiniHues与MiniHues.config的类型与字段值、autoadjust切换后的高亮调整、以及make_palette()→apply_palette()→get_palette()的完整应用闭环。阅读测试可以更直观地理解每个配置项的实际约束,例如背景色校验与配色方案重载时的行为。
与 mini.base16 的关系
mini.nvim 中还有一个 mini.base16 模块,它同样基于基础色生成配色方案,但遵循 Base16 规范、使用预定义的十六色系统。如果你的需求是 Base16 风格的固定模板配色,可参考 readmes/mini-base16.md;而 mini.hues 的优势在于基于 Oklch 的感知均匀计算与更细粒度的色相/饱和度/强调色控制。两者面向不同偏好,可按需选择。
【免费下载链接】mini.nvimLibrary of 45+ independent Lua modules improving Neovim experience with minimal effort项目地址: https://gitcode.com/GitHub_Trending/mi/mini.nvim
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考