From dc7216abbaf03ca6bc16e4397231fd8bb4c081de Mon Sep 17 00:00:00 2001
From: Meow Honk <21010072+catgoose@users.noreply.github.com>
Date: Sun, 22 Dec 2024 10:46:22 -0600
Subject: [PATCH] Fix/110 add names custom nonalpha chars to trie (#113)
* fix: fixes incorrect reference to sass name parser
* feat(Trie): adds method to add additional valid characters to Trie index_lookup
* chore: moves TODO comment which causes luadoc to skip function
---
doc/colorizer.txt | 4 +--
doc/modules/colorizer.sass.html | 6 ++--
lua/colorizer/config.lua | 2 +-
lua/colorizer/matcher.lua | 1 +
lua/colorizer/parser/names.lua | 63 ++++++++++++++++++++++++---------
lua/colorizer/sass.lua | 2 +-
lua/colorizer/trie.lua | 21 ++++++++---
lua/colorizer/utils.lua | 1 +
test/expect.lua | 22 +++++-------
9 files changed, 80 insertions(+), 42 deletions(-)
diff --git a/doc/colorizer.txt b/doc/colorizer.txt
index c54f4d3..1f3b8be 100644
--- a/doc/colorizer.txt
+++ b/doc/colorizer.txt
@@ -910,7 +910,7 @@ LUA API *colorizer.sass-lua-api*
Functions: ~
|cleanup| - Cleanup sass variables and watch handlers
- |name_parser| - Parse the given line for sass color names
+ |parser| - Parse the given line for sass color names
check for value in state[buf].definitions_all
|update_variables| - Parse the given lines for sass variabled and add to
@@ -925,7 +925,7 @@ cleanup({bufnr}) *colorizer.sass.cleanup*
-name_parser({line}, {i}, {bufnr}) *colorizer.sass.name_parser*
+parser({line}, {i}, {bufnr}) *colorizer.sass.parser*
Parse the given line for sass color names
check for value in state[buf].definitions_all
diff --git a/doc/modules/colorizer.sass.html b/doc/modules/colorizer.sass.html
index 7e2d66d..70e4a88 100644
--- a/doc/modules/colorizer.sass.html
+++ b/doc/modules/colorizer.sass.html
@@ -75,7 +75,7 @@
Cleanup sass variables and watch handlers |
- name_parser (line, i, bufnr) |
+ parser (line, i, bufnr) |
Parse the given line for sass color names
check for value in state[buf].definitions_all |
@@ -113,8 +113,8 @@ Parameters:
-
- name_parser (line, i, bufnr)
+
+ parser (line, i, bufnr)
Parse the given line for sass color names
diff --git a/lua/colorizer/config.lua b/lua/colorizer/config.lua
index 42a3403..9adff0a 100644
--- a/lua/colorizer/config.lua
+++ b/lua/colorizer/config.lua
@@ -233,7 +233,7 @@ function M.parse_buffer_options(options)
end
end
- -- https://github.com/NvChad/nvim-colorizer.lua/issues/48
+ -- https://github.com/catgoose/nvim-colorizer.lua/issues/48
handle_alias("css", options, default)
handle_alias("css_fn", options, default)
diff --git a/lua/colorizer/matcher.lua b/lua/colorizer/matcher.lua
index 25b076c..551b6c2 100644
--- a/lua/colorizer/matcher.lua
+++ b/lua/colorizer/matcher.lua
@@ -15,6 +15,7 @@ local parsers = {
hsl_function = require("colorizer.parser.hsl").parser,
rgb_function = require("colorizer.parser.rgb").parser,
rgba_hex = require("colorizer.parser.rgba_hex").parser,
+ -- TODO: 2024-12-21 - Should this be moved into parsers module?
sass_name = require("colorizer.sass").parser,
}
diff --git a/lua/colorizer/parser/names.lua b/lua/colorizer/parser/names.lua
index 0ee2920..8988ede 100644
--- a/lua/colorizer/parser/names.lua
+++ b/lua/colorizer/parser/names.lua
@@ -34,6 +34,22 @@ local function add_color(name, value)
names_cache.color_trie:insert(name)
end
+--- Extract non-alphanumeric characters to add as a valid index in the Trie
+-- @param tbl table The table to extract non-alphanumeric characters from.
+local function extract_non_alphanum_keys(tbl)
+ local non_alphanum_chars = {}
+ for key, _ in pairs(tbl) do
+ for char in key:gmatch("[^%w]") do
+ non_alphanum_chars[char] = true
+ end
+ end
+ local result = ""
+ for char in pairs(non_alphanum_chars) do
+ result = result .. char
+ end
+ return result
+end
+
--- Handles additional color names provided as a table or function.
-- @param names_custom table|function|nil Additional color names to add.
local function handle_names_custom(names_custom)
@@ -42,7 +58,6 @@ local function handle_names_custom(names_custom)
end
local extra_data = {}
-
if type(names_custom) == "table" then
extra_data = names_custom
elseif type(names_custom) == "function" then
@@ -57,6 +72,10 @@ local function handle_names_custom(names_custom)
end
end
+ -- Add additional characters found in names_custom keys
+ local additonal_chars = extract_non_alphanum_keys(names_custom)
+ names_cache.color_trie:additional_chars(additonal_chars)
+
for name, hex in pairs(extra_data) do
if type(hex) == "string" then
local normalized_hex = hex:gsub("^#", ""):gsub("%s", "")
@@ -73,6 +92,30 @@ local function handle_names_custom(names_custom)
end
end
+--- Handles Tailwind CSS colors and adds them to the Trie and map.
+local function handle_tailwind()
+ names_cache.color_trie:additional_chars("-")
+ local tailwind = require("colorizer.tailwind_colors")
+ for name, hex in pairs(tailwind.colors) do
+ for _, prefix in ipairs(tailwind.prefixes) do
+ add_color(prefix .. "-" .. name, hex)
+ end
+ end
+end
+
+--- Handles Vim's color map and adds colors to the Trie and map.
+local function handle_names()
+ for name, value in pairs(vim.api.nvim_get_color_map()) do
+ if not (names_cache.color_name_settings.strip_digits and name:match("%d+$")) then
+ local rgb_hex = tohex(value, 6)
+ add_color(name, rgb_hex)
+ if names_cache.color_name_settings.lowercase then
+ add_color(name:lower(), rgb_hex)
+ end
+ end
+ end
+end
+
--- Populates the Trie and map with colors based on options.
-- @param opts table Configuration options for color names and Tailwind CSS.
local function populate_colors(opts)
@@ -82,25 +125,12 @@ local function populate_colors(opts)
-- Add Vim's color map
if opts.color_names then
- for name, value in pairs(vim.api.nvim_get_color_map()) do
- if not (names_cache.color_name_settings.strip_digits and name:match("%d+$")) then
- local rgb_hex = tohex(value, 6)
- add_color(name, rgb_hex)
- if names_cache.color_name_settings.lowercase then
- add_color(name:lower(), rgb_hex)
- end
- end
- end
+ handle_names()
end
-- Add Tailwind colors
if opts.tailwind then
- local tailwind = require("colorizer.tailwind_colors")
- for name, hex in pairs(tailwind.colors) do
- for _, prefix in ipairs(tailwind.prefixes) do
- add_color(prefix .. "-" .. name, hex)
- end
- end
+ handle_tailwind()
end
names_cache.tailwind_enabled = opts.tailwind
@@ -117,6 +147,7 @@ end
-- @return number|nil, string|nil Length of match and hex value if found.
function M.parser(line, i, opts)
if not names_cache.color_trie or opts.tailwind ~= names_cache.tailwind_enabled then
+ -- TODO: 2024-12-21 - Ensure that this is not being called too many times
populate_colors(opts)
end
diff --git a/lua/colorizer/sass.lua b/lua/colorizer/sass.lua
index eb9d55a..4726c47 100644
--- a/lua/colorizer/sass.lua
+++ b/lua/colorizer/sass.lua
@@ -37,7 +37,7 @@ end
---@param i number: Index of line from where to start parsing
---@param bufnr number: Buffer number
---@return number|nil, string|nil
-function M.name_parser(line, i, bufnr)
+function M.parser(line, i, bufnr)
local variable_name = line:match("^%$([%w_-]+)", i)
if variable_name then
local rgb_hex = state[bufnr].definitions_all[variable_name]
diff --git a/lua/colorizer/trie.lua b/lua/colorizer/trie.lua
index fbb7263..14571a4 100644
--- a/lua/colorizer/trie.lua
+++ b/lua/colorizer/trie.lua
@@ -54,12 +54,9 @@ end
local total_char = 255
local index_lookup = ffi.new("uint8_t[?]", total_char)
-local char_lookup = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
+local char_lookup = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
do
local b = string.byte
- local extra_char = {
- [b("-")] = true,
- }
local byte = {
["0"] = b("0"),
["9"] = b("9"),
@@ -75,7 +72,6 @@ do
index_lookup[i] = i - byte["A"] + 10
elseif i >= byte["a"] and i <= byte["z"] then
index_lookup[i] = i - byte["a"] + 10 + 26
- elseif extra_char[i] then
else
index_lookup[i] = total_char
end
@@ -247,6 +243,20 @@ local function trie_to_string(trie)
return table.concat(print_trie_table(as_table), "\n")
end
+local function trie_additional_chars(trie, chars)
+ if trie == nil or type(chars) ~= "string" then
+ return
+ end
+ for i = 1, #chars do
+ local char = chars:sub(i, i)
+ local char_byte = string.byte(char)
+ if index_lookup[char_byte] == total_char then
+ char_lookup = char_lookup .. char
+ index_lookup[char_byte] = total_char + 1
+ end
+ end
+end
+
local Trie_mt = {
__new = function(_, init)
local trie = trie_create()
@@ -261,6 +271,7 @@ local Trie_mt = {
longest_prefix = trie_longest_prefix,
extend = trie_extend,
destroy = trie_destroy,
+ additional_chars = trie_additional_chars,
},
__tostring = trie_to_string,
__gc = trie_destroy,
diff --git a/lua/colorizer/utils.lua b/lua/colorizer/utils.lua
index 00e39c4..a9f73a5 100644
--- a/lua/colorizer/utils.lua
+++ b/lua/colorizer/utils.lua
@@ -68,6 +68,7 @@ end
---@param byte number The byte to check.
---@return boolean `true` if the byte is valid, otherwise `false`.
function M.byte_is_valid_colorchar(byte)
+ -- TODO: 2024-12-21 - Is this check required?
return M.byte_is_alphanumeric(byte) or byte == ("-"):byte()
end
diff --git a/test/expect.lua b/test/expect.lua
index a02ab26..621fe5d 100644
--- a/test/expect.lua
+++ b/test/expect.lua
@@ -6,15 +6,11 @@ local opts = {
lua = {
names = true,
names_custom = {
- -- names = "#1F4770",
- names = "#791497",
- cool = "#3F3347",
- lua = "#107d3c",
- ["notcool"] = "#ee9240",
- redgreen = "#970000",
- asdf = "#234311",
- eeee = "#112238",
- -- lua
+ red_purple = "#017dac",
+ ["red=green"] = "#3700c2",
+ ["green@blue"] = "#e9e240",
+ ["green!blue"] = "#a9e042",
+ ["green!!blue"] = "#09e392",
},
-- names_custom = function()
-- local colors = require("kanagawa.colors").setup()
@@ -25,11 +21,6 @@ local opts = {
buftypes = { "*", "!prompt", "!popup" },
user_commands = true,
user_default_options = {
- names_custom = {
- -- names = "#1F4770",
- names = "#1740F7",
- lua = "#7407F1",
- },
names = false,
RGB = true,
RRGGBB = true,
@@ -69,6 +60,9 @@ Extra names:
oniViolet oniViolet2 crystalBlue springViolet1 springViolet2 springBlue
lightBlue waveAqua2
+Additional names with non-alphanumeric characters
+red_purple red=green green@blue green!blue green!!blue
+
Hexadecimal:
#RGB:
#F0F