diff options
| author | jgmdev <jgmdev@gmail.com> | 2023-05-15 00:59:20 -0400 |
|---|---|---|
| committer | jgmdev <jgmdev@gmail.com> | 2023-05-18 01:05:37 -0400 |
| commit | 00a0e9cac9f55e7fe5877ecc271bf2114ee88ddf (patch) | |
| tree | 9989a0480ff524418fa1cd4ddff9a951fc912db2 /data | |
| parent | 57474facc6f8201266345a322f54ec8a12a4b1b0 (diff) | |
| download | pragtical-00a0e9cac9f55e7fe5877ecc271bf2114ee88ddf.tar.gz pragtical-00a0e9cac9f55e7fe5877ecc271bf2114ee88ddf.zip | |
Add more syntax symbols
* Adds various symbols as discussed on #1000
* Adds color darkening and brightening functions to allow defining
fallbacks that just modify the base syntax symbols with the option
of making them brighter or darker.
Diffstat (limited to 'data')
| -rw-r--r-- | data/core/common.lua | 98 | ||||
| -rw-r--r-- | data/core/init.lua | 132 |
2 files changed, 230 insertions, 0 deletions
diff --git a/data/core/common.lua b/data/core/common.lua index b6c9db67..faa6eb97 100644 --- a/data/core/common.lua +++ b/data/core/common.lua @@ -81,6 +81,104 @@ function common.color(str) end +---Converts an RGB color value to HSV. Conversion formula +---adapted from http://en.wikipedia.org/wiki/HSV_color_space. +---Assumes r, g, and b are contained in the set [0, 255] and +---returns h, s, and v in the set [0, 1]. +---@param rgba renderer.color +---@return table hsva The HSV representation +function common.rgb_to_hsv(rgba) + local r, g, b, a = rgba[1], rgba[2], rgba[3], rgba[4] + r, g, b, a = r / 255, g / 255, b / 255, a / 255 + local max, min = math.max(r, g, b), math.min(r, g, b) + local h, s, v + v = max + + local d = max - min + if max == 0 then s = 0 else s = d / max end + + if max == min then + h = 0 -- achromatic + else + if max == r then + h = (g - b) / d + if g < b then h = h + 6 end + elseif max == g then h = (b - r) / d + 2 + elseif max == b then h = (r - g) / d + 4 + end + h = h / 6 + end + + return {h, s, v, a} +end + + +---Converts an HSV color value to RGB. Conversion formula +---adapted from http://en.wikipedia.org/wiki/HSV_color_space. +---Assumes h, s, and v are contained in the set [0, 1] and +---returns r, g, and b in the set [0, 255]. +---@param h number The hue +---@param s number The saturation +---@param v number The brightness +---@param a number The alpha +---@return renderer.color rgba The RGB representation +function common.hsv_to_rgb(h, s, v, a) + local r, g, b + + local i = math.floor(h * 6); + local f = h * 6 - i; + local p = v * (1 - s); + local q = v * (1 - f * s); + local t = v * (1 - (1 - f) * s); + + i = i % 6 + + if i == 0 then r, g, b = v, t, p + elseif i == 1 then r, g, b = q, v, p + elseif i == 2 then r, g, b = p, v, t + elseif i == 3 then r, g, b = p, q, v + elseif i == 4 then r, g, b = t, p, v + elseif i == 5 then r, g, b = v, p, q + end + + return {math.ceil(r * 255), math.ceil(g * 255), math.ceil(b * 255), math.ceil(a * 255)} +end + + +---Makes a color brighter by the given percentage. +---@param rgba renderer.color +---@param percent integer +---@return renderer.color +function common.lighten_color(rgba, percent) + local hsva = common.rgb_to_hsv(rgba) + if hsva[3] < 1 then + local brightness = 100 / percent + hsva[3] = common.clamp(hsva[3]+brightness, 0, 1) + elseif hsva[2] > 0 then + local saturation = 100 / percent + hsva[2] = common.clamp(hsva[2]-saturation, 0, 1) + end + return common.hsv_to_rgb(table.unpack(hsva)) +end + + +---Makes a color darker by the given percentage. +---@param rgba renderer.color +---@param percent integer +---@return renderer.color +function common.darken_color(rgba, percent) + local hsva = common.rgb_to_hsv(rgba) + if hsva[3] > 0 then + local brightness = percent / 100 + hsva[3] = common.clamp(hsva[3]-brightness, 0, 1) + elseif hsva[2] < 1 then + local saturation = 100 / percent + hsva[2] = common.clamp(hsva[2]+saturation, 0, 1) + end + return common.hsv_to_rgb(table.unpack(hsva)) +end + + function common.splice(t, at, remove, insert) assert(remove >= 0, "bad argument #3 to 'splice' (non-negative value expected)") insert = insert or {} diff --git a/data/core/init.lua b/data/core/init.lua index 050a8ee2..9b972dbe 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -1078,14 +1078,146 @@ function core.load_project_module() end +---Additional syntax symbols that may not be defined by all color schemes +local symbols_map = { + -- symbols related to doc comments + ["annotation"] = { alt = "keyword", dec=25 }, + ["annotation.string"] = { alt = "string", dec=25 }, + ["annotation.param"] = { alt = "symbol", dec=25 }, + ["annotation.type"] = { alt = "keyword2", dec=25 }, + ["annotation.operator"] = { alt = "operator", dec=25 }, + ["annotation.function"] = { alt = "function", dec=25 }, + ["attribute"] = { alt = "keyword", dec=25 }, + -- Keywords like: true or false + ["boolean"] = { alt = "literal" }, + -- Single quote sequences like: 'a' + ["character"] = { alt = "string" }, + -- can be escape sequences like: \t, \r, \n + ["character.special"] = { }, + -- Keywords like: if, else, elseif + ["conditional" ] = { alt = "keyword" }, + -- conditional ternary as: condition ? value1 : value2 + ["conditional.ternary"] = { alt = "operator" }, + -- keywords like: nil, null + ["constant"] = { alt = "number" }, + ["constant.builtin"] = { }, + -- a macro constant as in: #define MYVAL 1 + ["constant.macro"] = { }, + -- constructor declarations as in: __constructor() or myclass::myclass() + ["constructor"] = { alt = "function" }, + ["debug"] = { alt = "comment" }, + ["define"] = { alt = "keyword" }, + ["error"] = { alt = "keyword" }, + -- keywords like: try, catch, finally + ["exception"] = { alt = "keyword" }, + -- class or table fields + ["field"] = { alt = "normal" }, + -- a numerical constant that holds a float + ["float"] = { alt = "number" }, + -- function name in a call + ["function.call"] = { }, + -- a function call that was declared as a macro like in: #define myfunc() + ["function.macro"] = { }, + -- keywords like: include, import, require + ["include"] = { alt = "keyword" }, + -- keywords like: return + ["keyword.return"] = { }, + -- keywords like: func, function + ["keyword.function"] = { }, + -- keywords like: and, or + ["keyword.operator"] = { }, + -- a goto label name like in: label: or ::label:: + ["label"] = { alt = "function" }, + -- class method declaration + ["method"] = { alt = "function" }, + -- class method call + ["method.call"] = { }, + -- namespace name like in namespace::subelement or namespace\subelement + ["namespace"] = { alt = "literal" }, + -- parameters in a function declaration + ["parameter"] = { alt = "operator" }, + -- keywords like: #if, #elif, #endif + ["preproc"] = { alt = "keyword" }, + -- any type of punctuation + ["punctuation"] = { alt = "normal" }, + -- punctuation like: (), {}, [] + ["punctuation.brackets"] = { }, + -- punctuation like: , or : + ["punctuation.delimiter"] = { alt = "operator" }, + -- puctuation like: # or @ + ["punctuation.special"] = { alt = "operator" }, + -- keywords like: while, for + ["repeat"] = { alt = "keyword" }, + -- keywords like: static, const, constexpr + ["storageclass"] = { alt = "keyword" }, + ["storageclass.lifetime"] = { }, + -- additions on diff or patch + ["text.diff.add"] = { alt = style.good }, + -- deletions on diff or patch + ["text.diff.delete"] = { alt = style.error }, + -- a language standard library support types + ["type"] = { alt = "keyword2" }, + -- a language builtin types like: char, double, int + ["type.builtin"] = { }, + -- a custom type defininition like ssize_t on typedef long int ssize_t + ["type.definition"] = { }, + -- keywords like: private, public + ["type.qualifier"] = { }, + -- any variable defined or accessed on the code + ["variable"] = { alt = "normal" }, + -- keywords like: this, self, parent + ["variable.builtin"] = { alt = "keyword2" }, +} + +local function map_missing_syntax_colors() + --- map symbols not defined on syntax + for symbol_name in pairs(symbols_map) do + if not style.syntax[symbol_name] then + local sections = {}; + for match in (symbol_name.."."):gmatch("(.-)%.") do + table.insert(sections, match); + end + for i=#sections, 1, -1 do + local section = table.concat(sections, ".", 1, i) + local parent = symbols_map[section] + if parent and parent.alt then + -- copy the color + local color = table.pack( + table.unpack(style.syntax[parent.alt] or parent.alt) + ) + if parent.dec then + color = common.darken_color(color, parent.dec) + elseif parent.inc then + color = common.lighten_color(color, parent.inc) + end + style.syntax[symbol_name] = color + break + end + end + end + end +end + + function core.reload_module(name) local old = package.loaded[name] + local is_color_scheme = name:match("^colors%..*") package.loaded[name] = nil + -- clear previous color scheme symbols + if is_color_scheme then + for symbol in pairs(symbols_map) do + style.syntax[symbol] = nil + end + end local new = require(name) if type(old) == "table" then for k, v in pairs(new) do old[k] = v end package.loaded[name] = old end + -- map colors that may be missing on the theme + if is_color_scheme then + map_missing_syntax_colors() + end end |
