summaryrefslogtreecommitdiff
path: root/config/nvim/lua/theme/colors256.lua
blob: 350a2a1313bf43436be4ea062f3c88357be62e53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
-- Hex to 256 color conversion utilities

local M = {}

-- Convert hex color to RGB values
local function hex_to_rgb(hex)
	hex = hex:gsub("#", "")
	return {
		r = tonumber(hex:sub(1, 2), 16),
		g = tonumber(hex:sub(3, 4), 16),
		b = tonumber(hex:sub(5, 6), 16),
	}
end

-- Convert RGB to nearest 256 color index
local function rgb_to_256(r, g, b)
	-- Build full 256 color palette and find nearest
	local palette = {}

	-- Gray ramp (232-255)
	for i = 0, 23 do
		local gray = 8 + i * 10
		palette[#palette + 1] = { r = gray, g = gray, b = gray, idx = 232 + i }
	end

	-- 6x6x6 color cube (16-231)
	local values = {0, 95, 135, 175, 215, 255}
	for ri = 0, 5 do
		for gi = 0, 5 do
			for bi = 0, 5 do
				local idx = 16 + ri * 36 + gi * 6 + bi
				palette[#palette + 1] = {
					r = values[ri + 1],
					g = values[gi + 1],
					b = values[bi + 1],
					idx = idx
				}
			end
		end
	end

	-- Find nearest color (minimum Manhattan distance)
	local min_dist = 100000
	local nearest_idx = 15

	for _, color in ipairs(palette) do
		local dist = math.abs(r - color.r) + math.abs(g - color.g) + math.abs(b - color.b)
		if dist < min_dist then
			min_dist = dist
			nearest_idx = color.idx
		end
	end

	return nearest_idx
end

-- Convert hex color string to 256 color index
function M.hex_to_256(hex)
	if not hex or hex == "" or hex == "NONE" then
		return nil
	end

	if type(hex) == "number" then
		return hex -- Already a cterm color
	end

	local rgb = hex_to_rgb(hex)
	return rgb_to_256(rgb.r, rgb.g, rgb.b)
end

-- Create highlight table with cterm colors from fg and bg hex colors
function M.convert_theme_theme(theme)
	local cterm_theme = {}
	for group, hl in pairs(theme) do
		local cterm = {}
		if hl.fg then
			cterm.fg = M.hex_to_256(hl.fg)
		end
		-- Include background colors
		if hl.bg then
			cterm.bg = M.hex_to_256(hl.bg)
		end
		if hl.sp then
			cterm.sp = M.hex_to_256(hl.sp)
		end
		if hl.bold then
			cterm.bold = true
		end
		if hl.underline then
			cterm.underline = true
		end
		if hl.undercurl then
			cterm.undercurl = true
		end
		if hl.italic then
			cterm.italic = true
		end
		if hl.reverse then
			cterm.reverse = true
		end
		if hl.standout then
			cterm.standout = true
		end

		cterm_theme[group] = cterm
	end
	return cterm_theme
end

return M