aboutsummaryrefslogtreecommitdiff
path: root/.config/vis/plugins/vis-colorizer/init.lua
blob: 9fa3a6ac0cffc2b2d1248e9d9627655d4ec779ac (plain)
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
local M = {
  text_colors = {
    dark = "#000000",
    light = "#ffffff"
  },
  -- Highlight six digit hex color codes
  six = true,
  -- Highlight three digit hex color hexcodes
  three = false,
}

local styleIdStack = {}

M.styleIdIterator = function()
	local i = 0
	local MAX_STYLE_ID = 64 -- UI_STYLE_LEXER_MAX = 64
	return function()
		i = i + 1
		if i <= MAX_STYLE_ID then
			return i
		end
		return nil
	end
end

M.initStyleIds = function()
	styleIdStack = {}
		for i in M.styleIdIterator() do
			table.insert(styleIdStack, i)
	end
end

M.initStyleIds()

M.extract_hex_colors = function(input_string)
	local pattern = "#([0-9a-fA-F]+)"
	local matches = {}

	local init = 1
	local match_end = 0
	while true do
		match_start, match_end, hex = string.find(input_string, pattern, init + match_end)
		-- TODO: add better validation
		if match_start == nil or hex == nil then
			break
		end
		if (hex:len() == 3 and M.three)  or (hex:len() == 6 and M.six) then
			table.insert(matches, {
				starts = match_start,
				ends = match_end,
				hex = hex,
			})
		end
	end

	return matches
end

M.draw = function(win, colors)
	local offset = win.viewport['bytes'].start
	for i, color in ipairs(colors) do
		local fg = M.text_colors.light

		if color.hex:len() == 3 then
			color.hex = string.gsub(color.hex,
				"([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])",
				"%1%1%2%2%3%3")
		end

		local r = tonumber(color.hex:sub(1, 2), 16)
		local g = tonumber(color.hex:sub(3, 4), 16)
		local b = tonumber(color.hex:sub(5, 6), 16)

		if (r * 30) + (g * 59) + (b * 11) > 12000 then
			fg = M.text_colors.dark
		end

		local id = table.remove(styleIdStack)

		local style = "fore:" .. fg .. ",back:#" .. color.hex
		if not win:style_define(id, style) then
			break
		end
		win:style(id, color.starts - 1 + offset, color.ends - 1 + offset)
		table.insert(styleIdStack, id)
		if color.ends >= win.viewport['bytes'].finish then
			break
		end
	end
end

M.on_higlight = function(win)
	local content = win.file:content(win.viewport['bytes'])
	local hex_colors = M.extract_hex_colors(content)
	M.draw(win, hex_colors)
end

vis.events.subscribe(vis.events.WIN_HIGHLIGHT, M.on_higlight)

return M