craftzdog.solarized-osaka.nvim/lua/solarized-osaka/util.lua
Takuya Matsuyama 0df74ef0ed refactor(colors): Source every color from the palette and drop darken
Point the last computed colors at real tokens so nothing is derived by
blending anymore:

- barbar inactive labels take the new 600 tier, which reads dimmer than
  the 500 accent and, unlike 700, still brightens under the vivid style
- notify borders take the 900 tier, and the debug border takes base02
- black was a blend of the background toward pure black, a value that
  appeared nowhere in the palette; it is base04, so replace it outright
- border was aliased to black, leaving it invisible against the
  background in the dark style; it is now base02, matching WinSeparator

With no callers left, darken and blend go, and with them the mutable
util.bg they relied on -- a shared global whose value depended on which
style had been resolved last.

Every highlight group is unchanged by the black removal. The barbar and
notify groups do shift slightly, since a token can never reproduce a
blend toward the background exactly; they were chosen to read correctly
rather than to match the old values.

Light gains from this: black resolved to a muddy #cac4b5 that measured
1.85:1 on statusline mode chips, and base04 lifts that to 3.21:1. The
same change makes terminal color0 white in the light style, completing
an inversion that already had color7 resolving to a dark value.
2026-08-11 15:38:54 +09:00

71 lines
1.9 KiB
Lua

local M = {}
--- Raises a color's perceptual lightness without draining its colorfulness.
---
---@param hex string
---@param amount number between 0 and 1, from unchanged to white
---@return string
function M.brighten(hex, amount)
if hex == "NONE" then
return hex
end
local hsluv = require("solarized-osaka.hsluv")
local lch = hsluv.rgb_to_lch(hsluv.hex_to_rgb(hex))
local chroma, hue = lch[2], lch[3]
local ceiling_before = hsluv.max_safe_chroma_for_lh(lch[1], hue)
lch[1] = lch[1] + (100 - lch[1]) * amount
-- Colors already sitting on the gamut boundary should ride it up rather than
-- stay pinned to their old chroma, so track the ceiling as well as the floor.
local ceiling = hsluv.max_safe_chroma_for_lh(lch[1], hue)
local scaled = ceiling_before > 0 and chroma * ceiling / ceiling_before or 0
lch[2] = math.min(math.max(chroma, scaled), ceiling)
local rgb = hsluv.lch_to_rgb(lch)
for i = 1, 3 do
rgb[i] = math.min(math.max(rgb[i], 0), 1)
end
return hsluv.rgb_to_hex(rgb)
end
-- Simple string interpolation.
--
-- Example template: "${name} is ${value}"
--
---@param str string template string
---@param table table key value pairs to replace in the string
function M.template(str, table)
return (
str:gsub("($%b{})", function(w)
return vim.tbl_get(table, unpack(vim.split(w:sub(3, -2), ".", { plain = true }))) or w
end)
)
end
local me = debug.getinfo(1, "S").source:sub(2)
me = vim.fn.fnamemodify(me, ":h:h")
function M.mod(modname)
if package.loaded[modname] then
return package.loaded[modname]
end
local ret = loadfile(me .. "/" .. modname:gsub("%.", "/") .. ".lua")()
package.loaded[modname] = ret
return ret
end
function M.resolve(groups)
for _, hl in pairs(groups) do
if type(hl.style) == "table" then
for k, v in pairs(hl.style) do
hl[k] = v
end
hl.style = nil
end
end
return groups
end
return M