aboutsummaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
authorjgmdev <jgmdev@gmail.com>2023-05-15 00:59:20 -0400
committerjgmdev <jgmdev@gmail.com>2023-05-18 01:05:37 -0400
commit00a0e9cac9f55e7fe5877ecc271bf2114ee88ddf (patch)
tree9989a0480ff524418fa1cd4ddff9a951fc912db2 /data
parent57474facc6f8201266345a322f54ec8a12a4b1b0 (diff)
downloadpragtical-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.lua98
-rw-r--r--data/core/init.lua132
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