craftzdog.solarized-osaka.nvim/lua/solarized-osaka/util.lua
Takuya Matsuyama 6f3bcf9cd9 refactor(util): Remove dead color and highlight helpers
The light style is a hand-written palette rather than an inversion of the
dark one, so the invert helpers lost their last caller. They only ever
called each other, and the same is true of syntax and highlight. lighten
had no callers at all.

Removing highlight orphans treesitter.lua, whose only consumer was the
ts.get call inside it, so the module goes too. day_brightness fed nothing
but invert_color and was already a no-op, so drop the option and its docs.

Also fix the vimdoc palette example, which called the now-removed
util.lighten with colors.bg_dark and colors.red1 -- tokyonight names that
have never existed in this fork.

All 2822 highlight groups across the dark, light and vivid styles are
byte-for-byte identical before and after, and the extras rebuild clean.
2026-08-11 14:49:45 +09:00

99 lines
2.8 KiB
Lua

local M = {}
M.bg = "#000000"
---@param c string
local function hexToRgb(c)
c = string.lower(c)
return { tonumber(c:sub(2, 3), 16), tonumber(c:sub(4, 5), 16), tonumber(c:sub(6, 7), 16) }
end
---@param foreground string foreground color
---@param background string background color
---@param alpha number|string number between 0 and 1. 0 results in bg, 1 results in fg
function M.blend(foreground, background, alpha)
alpha = type(alpha) == "string" and (tonumber(alpha, 16) / 0xff) or alpha
local bg = hexToRgb(background)
local fg = hexToRgb(foreground)
local blendChannel = function(i)
local ret = (alpha * fg[i] + ((1 - alpha) * bg[i]))
return math.floor(math.min(math.max(0, ret), 255) + 0.5)
end
return string.format("#%02x%02x%02x", blendChannel(1), blendChannel(2), blendChannel(3))
end
function M.darken(hex, amount, bg)
return M.blend(hex, bg or M.bg, amount)
end
--- 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