184 lines
4.5 KiB
Lua
184 lines
4.5 KiB
Lua
local M = {}
|
|
|
|
M.bg = "#000000"
|
|
M.fg = "#ffffff"
|
|
M.day_brightness = 0.3
|
|
|
|
---@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 fg string foreground color
|
|
---@param bg string background color
|
|
---@param alpha number number between 0 and 1. 0 results in bg, 1 results in fg
|
|
function M.blend(fg, bg, alpha)
|
|
bg = hexToRgb(bg)
|
|
fg = hexToRgb(fg)
|
|
|
|
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, math.abs(amount))
|
|
end
|
|
function M.lighten(hex, amount, fg)
|
|
return M.blend(hex, fg or M.fg, math.abs(amount))
|
|
end
|
|
|
|
function M.invert_color(color)
|
|
local hsluv = require("tokyonight.hsluv")
|
|
if color ~= "NONE" then
|
|
local hsl = hsluv.hex_to_hsluv(color)
|
|
hsl[3] = 100 - hsl[3]
|
|
if hsl[3] < 40 then
|
|
hsl[3] = hsl[3] + (100 - hsl[3]) * M.day_brightness
|
|
end
|
|
return hsluv.hsluv_to_hex(hsl)
|
|
end
|
|
return color
|
|
end
|
|
|
|
---@param group string
|
|
function M.highlight(group, color)
|
|
if group:sub(1,1) == "@" and vim.fn.has("nvim-0.8") == 0 then
|
|
return
|
|
end
|
|
local hl = { fg = color.fg, bg = color.bg, sp = color.sp, link = color.link }
|
|
if color.style and color.style:lower() ~= "none" then
|
|
for s in string.gmatch(color.style, "([^,]+)") do
|
|
hl[s] = true
|
|
end
|
|
end
|
|
vim.api.nvim_set_hl(0, group, hl)
|
|
end
|
|
|
|
--- Delete the autocmds when the theme changes to something else
|
|
function M.onColorScheme()
|
|
if vim.g.colors_name ~= "tokyonight" then
|
|
vim.cmd([[autocmd! TokyoNight]])
|
|
vim.cmd([[augroup! TokyoNight]])
|
|
end
|
|
end
|
|
|
|
---@param config Config
|
|
function M.autocmds(config)
|
|
vim.cmd([[augroup TokyoNight]])
|
|
vim.cmd([[ autocmd!]])
|
|
vim.cmd([[ autocmd ColorScheme * lua require("tokyonight.util").onColorScheme()]])
|
|
for _, sidebar in ipairs(config.sidebars) do
|
|
if sidebar == "terminal" then
|
|
vim.cmd([[ autocmd TermOpen * setlocal winhighlight=Normal:NormalSB,SignColumn:SignColumnSB]])
|
|
else
|
|
vim.cmd([[ autocmd FileType ]] .. sidebar .. [[ setlocal winhighlight=Normal:NormalSB,SignColumn:SignColumnSB]])
|
|
end
|
|
end
|
|
vim.cmd([[augroup end]])
|
|
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 table[w:sub(3, -2)] or w
|
|
end))
|
|
end
|
|
|
|
function M.syntax(syntax)
|
|
for group, colors in pairs(syntax) do
|
|
M.highlight(group, colors)
|
|
end
|
|
end
|
|
|
|
---@param colors ColorScheme
|
|
function M.terminal(colors)
|
|
-- dark
|
|
vim.g.terminal_color_0 = colors.black
|
|
vim.g.terminal_color_8 = colors.terminal_black
|
|
|
|
-- light
|
|
vim.g.terminal_color_7 = colors.fg_dark
|
|
vim.g.terminal_color_15 = colors.fg
|
|
|
|
-- colors
|
|
vim.g.terminal_color_1 = colors.red
|
|
vim.g.terminal_color_9 = colors.red
|
|
|
|
vim.g.terminal_color_2 = colors.green
|
|
vim.g.terminal_color_10 = colors.green
|
|
|
|
vim.g.terminal_color_3 = colors.yellow
|
|
vim.g.terminal_color_11 = colors.yellow
|
|
|
|
vim.g.terminal_color_4 = colors.blue
|
|
vim.g.terminal_color_12 = colors.blue
|
|
|
|
vim.g.terminal_color_5 = colors.magenta
|
|
vim.g.terminal_color_13 = colors.magenta
|
|
|
|
vim.g.terminal_color_6 = colors.cyan
|
|
vim.g.terminal_color_14 = colors.cyan
|
|
end
|
|
|
|
---@param colors ColorScheme
|
|
function M.invert_colors(colors)
|
|
if type(colors) == "string" then
|
|
---@diagnostic disable-next-line: return-type-mismatch
|
|
return M.invert_color(colors)
|
|
end
|
|
for key, value in pairs(colors) do
|
|
colors[key] = M.invert_colors(value)
|
|
end
|
|
end
|
|
|
|
---@param hls Highlights
|
|
function M.invert_highlights(hls)
|
|
for _, hl in pairs(hls) do
|
|
if hl.fg then
|
|
hl.fg = M.invert_color(hl.fg)
|
|
end
|
|
if hl.bg then
|
|
hl.bg = M.invert_color(hl.bg)
|
|
end
|
|
if hl.sp then
|
|
hl.sp = M.invert_color(hl.sp)
|
|
end
|
|
end
|
|
end
|
|
|
|
---@param theme Theme
|
|
function M.load(theme)
|
|
-- only needed to clear when not the default colorscheme
|
|
if vim.g.colors_name then
|
|
vim.cmd("hi clear")
|
|
end
|
|
|
|
vim.o.termguicolors = true
|
|
vim.g.colors_name = "tokyonight"
|
|
|
|
M.syntax(theme.highlights)
|
|
|
|
-- vim.api.nvim_set_hl_ns(M.ns)
|
|
if theme.config.terminal_colors then
|
|
M.terminal(theme.colors)
|
|
end
|
|
|
|
M.autocmds(theme.config)
|
|
|
|
vim.defer_fn(function()
|
|
M.syntax(theme.defer)
|
|
end, 100)
|
|
end
|
|
|
|
return M
|