aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.stylua.toml2
-rw-r--r--lua/colorizer.lua1193
-rw-r--r--lua/colorizer/nvim.lua398
-rw-r--r--lua/colorizer/trie.lua362
-rw-r--r--test/print-trie.lua96
5 files changed, 1057 insertions, 994 deletions
diff --git a/.stylua.toml b/.stylua.toml
index f4c1cee..ecb6dca 100644
--- a/.stylua.toml
+++ b/.stylua.toml
@@ -1,6 +1,6 @@
column_width = 120
line_endings = "Unix"
indent_type = "Spaces"
-indent_width = 3
+indent_width = 2
quote_style = "AutoPreferDouble"
call_parentheses = "None"
diff --git a/lua/colorizer.lua b/lua/colorizer.lua
index 9183f9e..f24c792 100644
--- a/lua/colorizer.lua
+++ b/lua/colorizer.lua
@@ -18,56 +18,56 @@ local COLOR_MAP
local COLOR_TRIE
local COLOR_NAME_MINLEN, COLOR_NAME_MAXLEN
local COLOR_NAME_SETTINGS = {
- lowercase = true,
- strip_digits = false,
+ lowercase = true,
+ strip_digits = false,
}
--- Setup the COLOR_MAP and COLOR_TRIE
local function initialize_trie()
- if not COLOR_TRIE then
- COLOR_MAP = {}
- COLOR_TRIE = Trie()
- for k, v in pairs(nvim.get_color_map()) do
- if not (COLOR_NAME_SETTINGS.strip_digits and k:match "%d+$") then
- COLOR_NAME_MINLEN = COLOR_NAME_MINLEN and min(#k, COLOR_NAME_MINLEN) or #k
- COLOR_NAME_MAXLEN = COLOR_NAME_MAXLEN and max(#k, COLOR_NAME_MAXLEN) or #k
- local rgb_hex = tohex(v, 6)
- COLOR_MAP[k] = rgb_hex
- COLOR_TRIE:insert(k)
- if COLOR_NAME_SETTINGS.lowercase then
- local lowercase = k:lower()
- COLOR_MAP[lowercase] = rgb_hex
- COLOR_TRIE:insert(lowercase)
- end
- end
- end
- end
+ if not COLOR_TRIE then
+ COLOR_MAP = {}
+ COLOR_TRIE = Trie()
+ for k, v in pairs(nvim.get_color_map()) do
+ if not (COLOR_NAME_SETTINGS.strip_digits and k:match "%d+$") then
+ COLOR_NAME_MINLEN = COLOR_NAME_MINLEN and min(#k, COLOR_NAME_MINLEN) or #k
+ COLOR_NAME_MAXLEN = COLOR_NAME_MAXLEN and max(#k, COLOR_NAME_MAXLEN) or #k
+ local rgb_hex = tohex(v, 6)
+ COLOR_MAP[k] = rgb_hex
+ COLOR_TRIE:insert(k)
+ if COLOR_NAME_SETTINGS.lowercase then
+ local lowercase = k:lower()
+ COLOR_MAP[lowercase] = rgb_hex
+ COLOR_TRIE:insert(lowercase)
+ end
+ end
+ end
+ end
end
local function merge(...)
- local res = {}
- for i = 1, select("#", ...) do
- local o = select(i, ...)
- for k, v in pairs(o) do
- res[k] = v
- end
- end
- return res
+ local res = {}
+ for i = 1, select("#", ...) do
+ local o = select(i, ...)
+ for k, v in pairs(o) do
+ res[k] = v
+ end
+ end
+ return res
end
local DEFAULT_OPTIONS = {
- RGB = true, -- #RGB hex codes
- RRGGBB = true, -- #RRGGBB hex codes
- names = true, -- "Name" codes like Blue or blue
- RRGGBBAA = false, -- #RRGGBBAA hex codes
- AARRGGBB = false, -- 0xAARRGGBB hex codes
- rgb_fn = false, -- CSS rgb() and rgba() functions
- hsl_fn = false, -- CSS hsl() and hsla() functions
- css = false, -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB
- css_fn = false, -- Enable all CSS *functions*: rgb_fn, hsl_fn
- -- Available modes: foreground, background, sign, virtualtext
- mode = "background", -- Set the display mode.
- virtualtext = "■",
+ RGB = true, -- #RGB hex codes
+ RRGGBB = true, -- #RRGGBB hex codes
+ names = true, -- "Name" codes like Blue or blue
+ RRGGBBAA = false, -- #RRGGBBAA hex codes
+ AARRGGBB = false, -- 0xAARRGGBB hex codes
+ rgb_fn = false, -- CSS rgb() and rgba() functions
+ hsl_fn = false, -- CSS hsl() and hsla() functions
+ css = false, -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB
+ css_fn = false, -- Enable all CSS *functions*: rgb_fn, hsl_fn
+ -- Available modes: foreground, background, sign, virtualtext
+ mode = "background", -- Set the display mode.
+ virtualtext = "■",
}
-- -- TODO use rgb as the return value from the matcher functions
@@ -87,207 +87,207 @@ local CATEGORY_ALPHA = lshift(1, 1)
local CATEGORY_HEX = lshift(1, 2)
local CATEGORY_ALPHANUM = bor(CATEGORY_ALPHA, CATEGORY_DIGIT)
do
- local b = string.byte
- for i = 0, 255 do
- local v = 0
- -- Digit is bit 1
- if i >= b "0" and i <= b "9" then
- v = bor(v, lshift(1, 0))
- v = bor(v, lshift(1, 2))
- v = bor(v, lshift(i - b "0", 4))
- end
- local lowercase = bor(i, 0x20)
- -- Alpha is bit 2
- if lowercase >= b "a" and lowercase <= b "z" then
- v = bor(v, lshift(1, 1))
- if lowercase <= b "f" then
- v = bor(v, lshift(1, 2))
- v = bor(v, lshift(lowercase - b "a" + 10, 4))
- end
- end
- BYTE_CATEGORY[i] = v
- end
+ local b = string.byte
+ for i = 0, 255 do
+ local v = 0
+ -- Digit is bit 1
+ if i >= b "0" and i <= b "9" then
+ v = bor(v, lshift(1, 0))
+ v = bor(v, lshift(1, 2))
+ v = bor(v, lshift(i - b "0", 4))
+ end
+ local lowercase = bor(i, 0x20)
+ -- Alpha is bit 2
+ if lowercase >= b "a" and lowercase <= b "z" then
+ v = bor(v, lshift(1, 1))
+ if lowercase <= b "f" then
+ v = bor(v, lshift(1, 2))
+ v = bor(v, lshift(lowercase - b "a" + 10, 4))
+ end
+ end
+ BYTE_CATEGORY[i] = v
+ end
end
local function byte_is_hex(byte)
- return band(BYTE_CATEGORY[byte], CATEGORY_HEX) ~= 0
+ return band(BYTE_CATEGORY[byte], CATEGORY_HEX) ~= 0
end
local function byte_is_alphanumeric(byte)
- local category = BYTE_CATEGORY[byte]
- return band(category, CATEGORY_ALPHANUM) ~= 0
+ local category = BYTE_CATEGORY[byte]
+ return band(category, CATEGORY_ALPHANUM) ~= 0
end
local function parse_hex(b)
- return rshift(BYTE_CATEGORY[b], 4)
+ return rshift(BYTE_CATEGORY[b], 4)
end
local function percent_or_hex(v)
- if v:sub(-1, -1) == "%" then
- return tonumber(v:sub(1, -2)) / 100 * 255
- end
- local x = tonumber(v)
- if x > 255 then
- return
- end
- return x
+ if v:sub(-1, -1) == "%" then
+ return tonumber(v:sub(1, -2)) / 100 * 255
+ end
+ local x = tonumber(v)
+ if x > 255 then
+ return
+ end
+ return x
end
--- Determine whether to use black or white text
-- Ref: https://stackoverflow.com/a/1855903/837964
-- https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
local function color_is_bright(r, g, b)
- -- Counting the perceptive luminance - human eye favors green color
- local luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
- if luminance > 0.5 then
- return true -- Bright colors, black font
- else
- return false -- Dark colors, white font
- end
+ -- Counting the perceptive luminance - human eye favors green color
+ local luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
+ if luminance > 0.5 then
+ return true -- Bright colors, black font
+ else
+ return false -- Dark colors, white font
+ end
end
-- https://gist.github.com/mjackson/5311256
local function hue_to_rgb(p, q, t)
- if t < 0 then
- t = t + 1
- end
- if t > 1 then
- t = t - 1
- end
- if t < 1 / 6 then
- return p + (q - p) * 6 * t
- end
- if t < 1 / 2 then
- return q
- end
- if t < 2 / 3 then
- return p + (q - p) * (2 / 3 - t) * 6
- end
- return p
+ if t < 0 then
+ t = t + 1
+ end
+ if t > 1 then
+ t = t - 1
+ end
+ if t < 1 / 6 then
+ return p + (q - p) * 6 * t
+ end
+ if t < 1 / 2 then
+ return q
+ end
+ if t < 2 / 3 then
+ return p + (q - p) * (2 / 3 - t) * 6
+ end
+ return p
end
local function hsl_to_rgb(h, s, l)
- if h > 1 or s > 1 or l > 1 then
- return
- end
- if s == 0 then
- local r = l * 255
- return r, r, r
- end
- local q
- if l < 0.5 then
- q = l * (1 + s)
- else
- q = l + s - l * s
- end
- local p = 2 * l - q
- return 255 * hue_to_rgb(p, q, h + 1 / 3), 255 * hue_to_rgb(p, q, h), 255 * hue_to_rgb(p, q, h - 1 / 3)
+ if h > 1 or s > 1 or l > 1 then
+ return
+ end
+ if s == 0 then
+ local r = l * 255
+ return r, r, r
+ end
+ local q
+ if l < 0.5 then
+ q = l * (1 + s)
+ else
+ q = l + s - l * s
+ end
+ local p = 2 * l - q
+ return 255 * hue_to_rgb(p, q, h + 1 / 3), 255 * hue_to_rgb(p, q, h), 255 * hue_to_rgb(p, q, h - 1 / 3)
end
local function color_name_parser(line, i)
- if i > 1 and byte_is_alphanumeric(line:byte(i - 1)) then
+ if i > 1 and byte_is_alphanumeric(line:byte(i - 1)) then
+ return
+ end
+ if #line < i + COLOR_NAME_MINLEN - 1 then
+ return
+ end
+ local prefix = COLOR_TRIE:longest_prefix(line, i)
+ if prefix then
+ -- Check if there is a letter here so as to disallow matching here.
+ -- Take the Blue out of Blueberry
+ -- Line end or non-letter.
+ local next_byte_index = i + #prefix
+ if #line >= next_byte_index and byte_is_alphanumeric(line:byte(next_byte_index)) then
return
- end
- if #line < i + COLOR_NAME_MINLEN - 1 then
- return
- end
- local prefix = COLOR_TRIE:longest_prefix(line, i)
- if prefix then
- -- Check if there is a letter here so as to disallow matching here.
- -- Take the Blue out of Blueberry
- -- Line end or non-letter.
- local next_byte_index = i + #prefix
- if #line >= next_byte_index and byte_is_alphanumeric(line:byte(next_byte_index)) then
- return
- end
- return #prefix, COLOR_MAP[prefix]
- end
+ end
+ return #prefix, COLOR_MAP[prefix]
+ end
end
local b_hash = ("#"):byte()
local function rgb_hex_parser(line, i, minlen, maxlen)
- if i > 1 and byte_is_alphanumeric(line:byte(i - 1)) then
- return
- end
- if line:byte(i) ~= b_hash then
- return
- end
- local j = i + 1
- if #line < j + minlen - 1 then
- return
- end
- local n = j + maxlen
- local alpha
- local v = 0
- while j <= min(n, #line) do
- local b = line:byte(j)
- if not byte_is_hex(b) then
- break
- end
- if j - i >= 7 then
- alpha = parse_hex(b) + lshift(alpha or 0, 4)
- else
- v = parse_hex(b) + lshift(v, 4)
- end
- j = j + 1
- end
- if #line >= j and byte_is_alphanumeric(line:byte(j)) then
- return
- end
- local length = j - i
- if length ~= 4 and length ~= 7 and length ~= 9 then
- return
- end
- if alpha then
- alpha = tonumber(alpha) / 255
- local r = floor(band(rshift(v, 16), 0xFF) * alpha)
- local g = floor(band(rshift(v, 8), 0xFF) * alpha)
- local b = floor(band(v, 0xFF) * alpha)
- v = bor(lshift(r, 16), lshift(g, 8), b)
- return 9, tohex(v, 6)
- end
- return length, line:sub(i + 1, i + length - 1)
+ if i > 1 and byte_is_alphanumeric(line:byte(i - 1)) then
+ return
+ end
+ if line:byte(i) ~= b_hash then
+ return
+ end
+ local j = i + 1
+ if #line < j + minlen - 1 then
+ return
+ end
+ local n = j + maxlen
+ local alpha
+ local v = 0
+ while j <= min(n, #line) do
+ local b = line:byte(j)
+ if not byte_is_hex(b) then
+ break
+ end
+ if j - i >= 7 then
+ alpha = parse_hex(b) + lshift(alpha or 0, 4)
+ else
+ v = parse_hex(b) + lshift(v, 4)
+ end
+ j = j + 1
+ end
+ if #line >= j and byte_is_alphanumeric(line:byte(j)) then
+ return
+ end
+ local length = j - i
+ if length ~= 4 and length ~= 7 and length ~= 9 then
+ return
+ end
+ if alpha then
+ alpha = tonumber(alpha) / 255
+ local r = floor(band(rshift(v, 16), 0xFF) * alpha)
+ local g = floor(band(rshift(v, 8), 0xFF) * alpha)
+ local b = floor(band(v, 0xFF) * alpha)
+ v = bor(lshift(r, 16), lshift(g, 8), b)
+ return 9, tohex(v, 6)
+ end
+ return length, line:sub(i + 1, i + length - 1)
end
local RGB_FUNCTION_TRIE = Trie { "0x" }
local function rgb_0x_parser(line, i)
- local prefix = RGB_FUNCTION_TRIE:longest_prefix(line:sub(i))
- if not prefix then
- return
- end
-
- local j = i + 2
- if #line < 10 then
- return
- end
- local n = j + 8
- local alpha
- local v = 0
- while j <= min(n, #line) do
- local b = line:byte(j)
- if not byte_is_hex(b) then
- break
- end
- if j - i <= 3 then
- alpha = parse_hex(b) + lshift(alpha or 0, 4)
- else
- v = parse_hex(b) + lshift(v, 4)
- end
- j = j + 1
- end
- if #line >= j and byte_is_alphanumeric(line:byte(j)) then
- return
- end
- local length = j - i
- if length ~= 10 then
- return
- end
- alpha = tonumber(alpha) / 255
- local r = floor(band(rshift(v, 16), 0xFF) * alpha)
- local g = floor(band(rshift(v, 8), 0xFF) * alpha)
- local b = floor(band(v, 0xFF) * alpha)
- v = bor(lshift(r, 16), lshift(g, 8), b)
- return length, tohex(v, 6)
+ local prefix = RGB_FUNCTION_TRIE:longest_prefix(line:sub(i))
+ if not prefix then
+ return
+ end
+
+ local j = i + 2
+ if #line < 10 then
+ return
+ end
+ local n = j + 8
+ local alpha
+ local v = 0
+ while j <= min(n, #line) do
+ local b = line:byte(j)
+ if not byte_is_hex(b) then
+ break
+ end
+ if j - i <= 3 then
+ alpha = parse_hex(b) + lshift(alpha or 0, 4)
+ else
+ v = parse_hex(b) + lshift(v, 4)
+ end
+ j = j + 1
+ end
+ if #line >= j and byte_is_alphanumeric(line:byte(j)) then
+ return
+ end
+ local length = j - i
+ if length ~= 10 then
+ return
+ end
+ alpha = tonumber(alpha) / 255
+ local r = floor(band(rshift(v, 16), 0xFF) * alpha)
+ local g = floor(band(rshift(v, 8), 0xFF) * alpha)
+ local b = floor(band(v, 0xFF) * alpha)
+ v = bor(lshift(r, 16), lshift(g, 8), b)
+ return length, tohex(v, 6)
end
-- TODO consider removing the regexes here
@@ -295,162 +295,159 @@ end
-- Things like pumblend might be useful here.
local css_fn = {}
do
- local CSS_RGB_FN_MINIMUM_LENGTH = #"rgb(0,0,0)" - 1
- local CSS_RGBA_FN_MINIMUM_LENGTH = #"rgba(0,0,0,0)" - 1
- local CSS_HSL_FN_MINIMUM_LENGTH = #"hsl(0,0%,0%)" - 1
- local CSS_HSLA_FN_MINIMUM_LENGTH = #"hsla(0,0%,0%,0)" - 1
- function css_fn.rgb(line, i)
- if #line < i + CSS_RGB_FN_MINIMUM_LENGTH then
- return
- end
- local r, g, b, match_end = line:sub(i):match "^rgb%(%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*(%d+%%?)%s*%)()"
- if not match_end then
- return
- end
- r = percent_or_hex(r)
- if not r then
- return
- end
- g = percent_or_hex(g)
- if not g then
- return
- end
- b = percent_or_hex(b)
- if not b then
- return
- end
- local rgb_hex = tohex(bor(lshift(r, 16), lshift(g, 8), b), 6)
- return match_end - 1, rgb_hex
- end
- function css_fn.hsl(line, i)
- if #line < i + CSS_HSL_FN_MINIMUM_LENGTH then
- return
- end
- local h, s, l, match_end = line:sub(i):match "^hsl%(%s*(%d+)%s*,%s*(%d+)%%%s*,%s*(%d+)%%%s*%)()"
- if not match_end then
- return
- end
- h = tonumber(h)
- if h > 360 then
- return
- end
- s = tonumber(s)
- if s > 100 then
- return
- end
- l = tonumber(l)
- if l > 100 then
- return
- end
- local r, g, b = hsl_to_rgb(h / 360, s / 100, l / 100)
- if r == nil or g == nil or b == nil then
- return
- end
- local rgb_hex = tohex(bor(lshift(floor(r), 16), lshift(floor(g), 8), floor(b)), 6)
- return match_end - 1, rgb_hex
- end
- function css_fn.rgba(line, i)
- if #line < i + CSS_RGBA_FN_MINIMUM_LENGTH then
- return
- end
- local r, g, b, a, match_end = line
- :sub(i)
- :match "^rgba%(%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*([.%d]+)%s*%)()"
- if not match_end then
- return
- end
- a = tonumber(a)
- if not a or a > 1 then
- return
- end
- r = percent_or_hex(r)
- if not r then
- return
- end
- g = percent_or_hex(g)
- if not g then
- return
- end
- b = percent_or_hex(b)
- if not b then
- return
- end
- local rgb_hex = tohex(bor(lshift(floor(r * a), 16), lshift(floor(g * a), 8), floor(b * a)), 6)
- return match_end - 1, rgb_hex
- end
- function css_fn.hsla(line, i)
- if #line < i + CSS_HSLA_FN_MINIMUM_LENGTH then
- return
- end
- local h, s, l, a, match_end = line
- :sub(i)
- :match "^hsla%(%s*(%d+)%s*,%s*(%d+)%%%s*,%s*(%d+)%%%s*,%s*([.%d]+)%s*%)()"
- if not match_end then
- return
- end
- a = tonumber(a)
- if not a or a > 1 then
- return
- end
- h = tonumber(h)
- if h > 360 then
- return
- end
- s = tonumber(s)
- if s > 100 then
- return
- end
- l = tonumber(l)
- if l > 100 then
- return
- end
- local r, g, b = hsl_to_rgb(h / 360, s / 100, l / 100)
- if r == nil or g == nil or b == nil then
- return
- end
- local rgb_hex = tohex(bor(lshift(floor(r * a), 16), lshift(floor(g * a), 8), floor(b * a)), 6)
- return match_end - 1, rgb_hex
- end
+ local CSS_RGB_FN_MINIMUM_LENGTH = #"rgb(0,0,0)" - 1
+ local CSS_RGBA_FN_MINIMUM_LENGTH = #"rgba(0,0,0,0)" - 1
+ local CSS_HSL_FN_MINIMUM_LENGTH = #"hsl(0,0%,0%)" - 1
+ local CSS_HSLA_FN_MINIMUM_LENGTH = #"hsla(0,0%,0%,0)" - 1
+ function css_fn.rgb(line, i)
+ if #line < i + CSS_RGB_FN_MINIMUM_LENGTH then
+ return
+ end
+ local r, g, b, match_end = line:sub(i):match "^rgb%(%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*(%d+%%?)%s*%)()"
+ if not match_end then
+ return
+ end
+ r = percent_or_hex(r)
+ if not r then
+ return
+ end
+ g = percent_or_hex(g)
+ if not g then
+ return
+ end
+ b = percent_or_hex(b)
+ if not b then
+ return
+ end
+ local rgb_hex = tohex(bor(lshift(r, 16), lshift(g, 8), b), 6)
+ return match_end - 1, rgb_hex
+ end
+ function css_fn.hsl(line, i)
+ if #line < i + CSS_HSL_FN_MINIMUM_LENGTH then
+ return
+ end
+ local h, s, l, match_end = line:sub(i):match "^hsl%(%s*(%d+)%s*,%s*(%d+)%%%s*,%s*(%d+)%%%s*%)()"
+ if not match_end then
+ return
+ end
+ h = tonumber(h)
+ if h > 360 then
+ return
+ end
+ s = tonumber(s)
+ if s > 100 then
+ return
+ end
+ l = tonumber(l)
+ if l > 100 then
+ return
+ end
+ local r, g, b = hsl_to_rgb(h / 360, s / 100, l / 100)
+ if r == nil or g == nil or b == nil then
+ return
+ end
+ local rgb_hex = tohex(bor(lshift(floor(r), 16), lshift(floor(g), 8), floor(b)), 6)
+ return match_end - 1, rgb_hex
+ end
+ function css_fn.rgba(line, i)
+ if #line < i + CSS_RGBA_FN_MINIMUM_LENGTH then
+ return
+ end
+ local r, g, b, a, match_end =
+ line:sub(i):match "^rgba%(%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*(%d+%%?)%s*,%s*([.%d]+)%s*%)()"
+ if not match_end then
+ return
+ end
+ a = tonumber(a)
+ if not a or a > 1 then
+ return
+ end
+ r = percent_or_hex(r)
+ if not r then
+ return
+ end
+ g = percent_or_hex(g)
+ if not g then
+ return
+ end
+ b = percent_or_hex(b)
+ if not b then
+ return
+ end
+ local rgb_hex = tohex(bor(lshift(floor(r * a), 16), lshift(floor(g * a), 8), floor(b * a)), 6)
+ return match_end - 1, rgb_hex
+ end
+ function css_fn.hsla(line, i)
+ if #line < i + CSS_HSLA_FN_MINIMUM_LENGTH then
+ return
+ end
+ local h, s, l, a, match_end = line:sub(i):match "^hsla%(%s*(%d+)%s*,%s*(%d+)%%%s*,%s*(%d+)%%%s*,%s*([.%d]+)%s*%)()"
+ if not match_end then
+ return
+ end
+ a = tonumber(a)
+ if not a or a > 1 then
+ return
+ end
+ h = tonumber(h)
+ if h > 360 then
+ return
+ end
+ s = tonumber(s)
+ if s > 100 then
+ return
+ end
+ l = tonumber(l)
+ if l > 100 then
+ return
+ end
+ local r, g, b = hsl_to_rgb(h / 360, s / 100, l / 100)
+ if r == nil or g == nil or b == nil then
+ return
+ end
+ local rgb_hex = tohex(bor(lshift(floor(r * a), 16), lshift(floor(g * a), 8), floor(b * a)), 6)
+ return match_end - 1, rgb_hex
+ end
end
local css_function_parser, rgb_function_parser, hsl_function_parser
do
- local CSS_FUNCTION_TRIE = Trie { "rgb", "rgba", "hsl", "hsla" }
- local RGB_FUNCTION_TRIE = Trie { "rgb", "rgba" }
- local HSL_FUNCTION_TRIE = Trie { "hsl", "hsla" }
- css_function_parser = function(line, i)
- local prefix = CSS_FUNCTION_TRIE:longest_prefix(line:sub(i))
- if prefix then
- return css_fn[prefix](line, i)
- end
- end
- rgb_function_parser = function(line, i)
- local prefix = RGB_FUNCTION_TRIE:longest_prefix(line:sub(i))
- if prefix then
- return css_fn[prefix](line, i)
- end
- end
- hsl_function_parser = function(line, i)
- local prefix = HSL_FUNCTION_TRIE:longest_prefix(line:sub(i))
- if prefix then
- return css_fn[prefix](line, i)
- end
- end
+ local CSS_FUNCTION_TRIE = Trie { "rgb", "rgba", "hsl", "hsla" }
+ local RGB_FUNCTION_TRIE = Trie { "rgb", "rgba" }
+ local HSL_FUNCTION_TRIE = Trie { "hsl", "hsla" }
+ css_function_parser = function(line, i)
+ local prefix = CSS_FUNCTION_TRIE:longest_prefix(line:sub(i))
+ if prefix then
+ return css_fn[prefix](line, i)
+ end
+ end
+ rgb_function_parser = function(line, i)
+ local prefix = RGB_FUNCTION_TRIE:longest_prefix(line:sub(i))
+ if prefix then
+ return css_fn[prefix](line, i)
+ end
+ end
+ hsl_function_parser = function(line, i)
+ local prefix = HSL_FUNCTION_TRIE:longest_prefix(line:sub(i))
+ if prefix then
+ return css_fn[prefix](line, i)
+ end
+ end
end
local function compile_matcher(matchers)
- local parse_fn = matchers[1]
- for j = 2, #matchers do
- local old_parse_fn = parse_fn
- local new_parse_fn = matchers[j]
- parse_fn = function(line, i)
- local length, rgb_hex = new_parse_fn(line, i)
- if length then
- return length, rgb_hex
- end
- return old_parse_fn(line, i)
- end
- end
- return parse_fn
+ local parse_fn = matchers[1]
+ for j = 2, #matchers do
+ local old_parse_fn = parse_fn
+ local new_parse_fn = matchers[j]
+ parse_fn = function(line, i)
+ local length, rgb_hex = new_parse_fn(line, i)
+ if length then
+ return length, rgb_hex
+ end
+ return old_parse_fn(line, i)
+ end
+ end
+ return parse_fn
end
--- Default namespace used in `highlight_buffer` and `attach_to_buffer`.
@@ -460,131 +457,131 @@ end
local DEFAULT_NAMESPACE = nvim.create_namespace "colorizer"
local HIGHLIGHT_NAME_PREFIX = "colorizer"
local HIGHLIGHT_MODE_NAMES = {
- background = "mb",
- foreground = "mf",
- virtualtext = "mv",
+ background = "mb",
+ foreground = "mf",
+ virtualtext = "mv",
}
local HIGHLIGHT_CACHE = {}
--- Make a deterministic name for a highlight given these attributes
local function make_highlight_name(rgb, mode)
- return table.concat({ HIGHLIGHT_NAME_PREFIX, HIGHLIGHT_MODE_NAMES[mode], rgb }, "_")
+ return table.concat({ HIGHLIGHT_NAME_PREFIX, HIGHLIGHT_MODE_NAMES[mode], rgb }, "_")
end
local function create_highlight(rgb_hex, options)
- local mode = options.mode or "background"
- -- TODO validate rgb format?
- rgb_hex = rgb_hex:lower()
- local cache_key = table.concat({ HIGHLIGHT_MODE_NAMES[mode], rgb_hex }, "_")
- local highlight_name = HIGHLIGHT_CACHE[cache_key]
- -- Look up in our cache.
- if not highlight_name then
- if #rgb_hex == 3 then
- rgb_hex = table.concat {
- rgb_hex:sub(1, 1):rep(2),
- rgb_hex:sub(2, 2):rep(2),
- rgb_hex:sub(3, 3):rep(2),
- }
- end
- -- Create the highlight
- highlight_name = make_highlight_name(rgb_hex, mode)
- if mode == "foreground" then
- nvim.ex.highlight(highlight_name, "guifg=#" .. rgb_hex)
+ local mode = options.mode or "background"
+ -- TODO validate rgb format?
+ rgb_hex = rgb_hex:lower()
+ local cache_key = table.concat({ HIGHLIGHT_MODE_NAMES[mode], rgb_hex }, "_")
+ local highlight_name = HIGHLIGHT_CACHE[cache_key]
+ -- Look up in our cache.
+ if not highlight_name then
+ if #rgb_hex == 3 then
+ rgb_hex = table.concat {
+ rgb_hex:sub(1, 1):rep(2),
+ rgb_hex:sub(2, 2):rep(2),
+ rgb_hex:sub(3, 3):rep(2),
+ }
+ end
+ -- Create the highlight
+ highlight_name = make_highlight_name(rgb_hex, mode)
+ if mode == "foreground" then
+ nvim.ex.highlight(highlight_name, "guifg=#" .. rgb_hex)
+ else
+ local r, g, b = rgb_hex:sub(1, 2), rgb_hex:sub(3, 4), rgb_hex:sub(5, 6)
+ r, g, b = tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
+ local fg_color
+ if color_is_bright(r, g, b) then
+ fg_color = "Black"
else
- local r, g, b = rgb_hex:sub(1, 2), rgb_hex:sub(3, 4), rgb_hex:sub(5, 6)
- r, g, b = tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
- local fg_color
- if color_is_bright(r, g, b) then
- fg_color = "Black"
- else
- fg_color = "White"
- end
- nvim.ex.highlight(highlight_name, "guifg=" .. fg_color, "guibg=#" .. rgb_hex)
+ fg_color = "White"
end
- HIGHLIGHT_CACHE[cache_key] = highlight_name
- end
- return highlight_name
+ nvim.ex.highlight(highlight_name, "guifg=" .. fg_color, "guibg=#" .. rgb_hex)
+ end
+ HIGHLIGHT_CACHE[cache_key] = highlight_name
+ end
+ return highlight_name
end
local MATCHER_CACHE = {}
local function make_matcher(options)
- local enable_names = options.css or options.names
- local enable_RGB = options.css or options.RGB
- local enable_RRGGBB = options.css or options.RRGGBB
- local enable_RRGGBBAA = options.css or options.RRGGBBAA
- local enable_AARRGGBB = options.AARRGGBB
- local enable_rgb = options.css or options.css_fns or options.rgb_fn
- local enable_hsl = options.css or options.css_fns or options.hsl_fn
-
- local matcher_key = bor(
- lshift(enable_names and 1 or 0, 0),
- lshift(enable_RGB and 1 or 0, 1),
- lshift(enable_RRGGBB and 1 or 0, 2),
- lshift(enable_RRGGBBAA and 1 or 0, 3),
- lshift(enable_rgb and 1 or 0, 4),
- lshift(enable_hsl and 1 or 0, 5)
- )
-
- if matcher_key == 0 then
- return
- end
-
- local loop_parse_fn = MATCHER_CACHE[matcher_key]
- if loop_parse_fn then
- return loop_parse_fn
- end
-
- local loop_matchers = {}
- if enable_names then
- table.insert(loop_matchers, color_name_parser)
- end
- if enable_AARRGGBB then
- table.insert(loop_matchers, rgb_0x_parser)
- end
- do
- local valid_lengths = { [3] = enable_RGB, [6] = enable_RRGGBB, [8] = enable_RRGGBBAA }
- local minlen, maxlen
- for k, v in pairs(valid_lengths) do
- if v then
- minlen = minlen and min(k, minlen) or k
- maxlen = maxlen and max(k, maxlen) or k
- end
- end
- if minlen then
- table.insert(loop_matchers, function(line, i)
- local length, rgb_hex = rgb_hex_parser(line, i, minlen, maxlen)
- if length and valid_lengths[length - 1] then
- return length, rgb_hex
- end
- end)
- end
- end
- if enable_rgb and enable_hsl then
- table.insert(loop_matchers, css_function_parser)
- elseif enable_rgb then
- table.insert(loop_matchers, rgb_function_parser)
- elseif enable_hsl then
- table.insert(loop_matchers, hsl_function_parser)
- end
- loop_parse_fn = compile_matcher(loop_matchers)
- MATCHER_CACHE[matcher_key] = loop_parse_fn
- return loop_parse_fn
+ local enable_names = options.css or options.names
+ local enable_RGB = options.css or options.RGB
+ local enable_RRGGBB = options.css or options.RRGGBB
+ local enable_RRGGBBAA = options.css or options.RRGGBBAA
+ local enable_AARRGGBB = options.AARRGGBB
+ local enable_rgb = options.css or options.css_fns or options.rgb_fn
+ local enable_hsl = options.css or options.css_fns or options.hsl_fn
+
+ local matcher_key = bor(
+ lshift(enable_names and 1 or 0, 0),
+ lshift(enable_RGB and 1 or 0, 1),
+ lshift(enable_RRGGBB and 1 or 0, 2),
+ lshift(enable_RRGGBBAA and 1 or 0, 3),
+ lshift(enable_rgb and 1 or 0, 4),
+ lshift(enable_hsl and 1 or 0, 5)
+ )
+
+ if matcher_key == 0 then
+ return
+ end
+
+ local loop_parse_fn = MATCHER_CACHE[matcher_key]
+ if loop_parse_fn then
+ return loop_parse_fn
+ end
+
+ local loop_matchers = {}
+ if enable_names then
+ table.insert(loop_matchers, color_name_parser)
+ end
+ if enable_AARRGGBB then
+ table.insert(loop_matchers, rgb_0x_parser)
+ end
+ do
+ local valid_lengths = { [3] = enable_RGB, [6] = enable_RRGGBB, [8] = enable_RRGGBBAA }
+ local minlen, maxlen
+ for k, v in pairs(valid_lengths) do
+ if v then
+ minlen = minlen and min(k, minlen) or k
+ maxlen = maxlen and max(k, maxlen) or k
+ end
+ end
+ if minlen then
+ table.insert(loop_matchers, function(line, i)
+ local length, rgb_hex = rgb_hex_parser(line, i, minlen, maxlen)
+ if length and valid_lengths[length - 1] then
+ return length, rgb_hex
+ end
+ end)
+ end
+ end
+ if enable_rgb and enable_hsl then
+ table.insert(loop_matchers, css_function_parser)
+ elseif enable_rgb then
+ table.insert(loop_matchers, rgb_function_parser)
+ elseif enable_hsl then
+ table.insert(loop_matchers, hsl_function_parser)
+ end
+ loop_parse_fn = compile_matcher(loop_matchers)
+ MATCHER_CACHE[matcher_key] = loop_parse_fn
+ return loop_parse_fn
end
local function add_highlight(options, buf, ns, data)
- for linenr, hls in pairs(data) do
- if vim.tbl_contains({ "foreground", "background" }, options.mode) then
- for _, hl in ipairs(hls) do
- nvim_buf_add_highlight(buf, ns, hl.name, linenr, hl.range[1], hl.range[2])
- end
- elseif options.mode == "virtualtext" then
- local chunks = {}
- for _, hl in ipairs(hls) do
- table.insert(chunks, { options.virtualtext, hl.name })
- end
- nvim_buf_set_virtual_text(buf, ns, linenr, chunks, {})
- end
- end
+ for linenr, hls in pairs(data) do
+ if vim.tbl_contains({ "foreground", "background" }, options.mode) then
+ for _, hl in ipairs(hls) do
+ nvim_buf_add_highlight(buf, ns, hl.name, linenr, hl.range[1], hl.range[2])
+ end
+ elseif options.mode == "virtualtext" then
+ local chunks = {}
+ for _, hl in ipairs(hls) do
+ table.insert(chunks, { options.virtualtext, hl.name })
+ end
+ nvim_buf_set_virtual_text(buf, ns, linenr, chunks, {})
+ end
+ end
end
--[[-- Highlight the buffer region.
@@ -599,30 +596,30 @@ buffer `buf` and attach it to the namespace `ns`.
@see setup
]]
local function highlight_buffer(buf, ns, lines, line_start, options)
- -- TODO do I have to put this here?
- initialize_trie()
- ns = ns or DEFAULT_NAMESPACE
- local loop_parse_fn = make_matcher(options)
- local data = {}
- local mode = options.mode == "background" and { mode = "background" } or { mode = "foreground" }
- for current_linenum, line in ipairs(lines) do
- current_linenum = current_linenum - 1 + line_start
- -- Upvalues are options and current_linenum
- local i = 1
- while i < #line do
- local length, rgb_hex = loop_parse_fn(line, i)
- if length then
- local name = create_highlight(rgb_hex, mode)
- local d = data[current_linenum] or {}
- table.insert(d, { name = name, range = { i - 1, i + length - 1 } })
- data[current_linenum] = d
- i = i + length
- else
- i = i + 1
- end
+ -- TODO do I have to put this here?
+ initialize_trie()
+ ns = ns or DEFAULT_NAMESPACE
+ local loop_parse_fn = make_matcher(options)
+ local data = {}
+ local mode = options.mode == "background" and { mode = "background" } or { mode = "foreground" }
+ for current_linenum, line in ipairs(lines) do
+ current_linenum = current_linenum - 1 + line_start
+ -- Upvalues are options and current_linenum
+ local i = 1
+ while i < #line do
+ local length, rgb_hex = loop_parse_fn(line, i)
+ if length then
+ local name = create_highlight(rgb_hex, mode)
+ local d = data[current_linenum] or {}
+ table.insert(d, { name = name, range = { i - 1, i + length - 1 } })
+ data[current_linenum] = d
+ i = i + length
+ else
+ i = i + 1
end
- end
- add_highlight(options, buf, ns, data)
+ end
+ end
+ add_highlight(options, buf, ns, data)
end
---
@@ -630,36 +627,36 @@ end
---
local SETUP_SETTINGS = {
- exclusions = {},
- default_options = DEFAULT_OPTIONS,
+ exclusions = {},
+ default_options = DEFAULT_OPTIONS,
}
local BUFFER_OPTIONS = {}
local FILETYPE_OPTIONS = {}
local function rehighlight_buffer(buf, options)
- local ns = DEFAULT_NAMESPACE
- if buf == 0 or buf == nil then
- buf = nvim_get_current_buf()
- end
- assert(options)
- nvim_buf_clear_namespace(buf, ns, 0, -1)
- local lines = nvim_buf_get_lines(buf, 0, -1, true)
- highlight_buffer(buf, ns, lines, 0, options)
+ local ns = DEFAULT_NAMESPACE
+ if buf == 0 or buf == nil then
+ buf = nvim_get_current_buf()
+ end
+ assert(options)
+ nvim_buf_clear_namespace(buf, ns, 0, -1)
+ local lines = nvim_buf_get_lines(buf, 0, -1, true)
+ highlight_buffer(buf, ns, lines, 0, options)
end
local function new_buffer_options(buf)
- local filetype = nvim.buf_get_option(buf, "filetype")
- return FILETYPE_OPTIONS[filetype] or SETUP_SETTINGS.default_options
+ local filetype = nvim.buf_get_option(buf, "filetype")
+ return FILETYPE_OPTIONS[filetype] or SETUP_SETTINGS.default_options
end
--- Check if attached to a buffer.
-- @tparam[opt=0|nil] integer buf A value of 0 implies the current buffer.
-- @return true if attached to the buffer, false otherwise.
local function is_buffer_attached(buf)
- if buf == 0 or buf == nil then
- buf = nvim_get_current_buf()
- end
- return BUFFER_OPTIONS[buf] ~= nil
+ if buf == 0 or buf == nil then
+ buf = nvim_get_current_buf()
+ end
+ return BUFFER_OPTIONS[buf] ~= nil
end
--- Attach to a buffer and continuously highlight changes.
@@ -667,45 +664,45 @@ end
-- @param[opt] options Configuration options as described in `setup`
-- @see setup
local function attach_to_buffer(buf, options)
- if buf == 0 or buf == nil then
- buf = nvim_get_current_buf()
- end
- local already_attached = BUFFER_OPTIONS[buf] ~= nil
- local ns = DEFAULT_NAMESPACE
- if not options then
- options = new_buffer_options(buf)
- end
- BUFFER_OPTIONS[buf] = options
- rehighlight_buffer(buf, options)
- if already_attached then
- return
- end
- -- send_buffer: true doesn't actually do anything in Lua (yet)
- nvim.buf_attach(buf, false, {
- on_lines = function(event_type, buf, changed_tick, firstline, lastline, new_lastline)
- -- This is used to signal stopping the handler highlights
- if not BUFFER_OPTIONS[buf] then
- return true
- end
- nvim_buf_clear_namespace(buf, ns, firstline, new_lastline)
- local lines = nvim_buf_get_lines(buf, firstline, new_lastline, false)
- highlight_buffer(buf, ns, lines, firstline, BUFFER_OPTIONS[buf])
- end,
- on_detach = function()
- BUFFER_OPTIONS[buf] = nil
- end,
- })
+ if buf == 0 or buf == nil then
+ buf = nvim_get_current_buf()
+ end
+ local already_attached = BUFFER_OPTIONS[buf] ~= nil
+ local ns = DEFAULT_NAMESPACE
+ if not options then
+ options = new_buffer_options(buf)
+ end
+ BUFFER_OPTIONS[buf] = options
+ rehighlight_buffer(buf, options)
+ if already_attached then
+ return
+ end
+ -- send_buffer: true doesn't actually do anything in Lua (yet)
+ nvim.buf_attach(buf, false, {
+ on_lines = function(event_type, buf, changed_tick, firstline, lastline, new_lastline)
+ -- This is used to signal stopping the handler highlights
+ if not BUFFER_OPTIONS[buf] then
+ return true
+ end
+ nvim_buf_clear_namespace(buf, ns, firstline, new_lastline)
+ local lines = nvim_buf_get_lines(buf, firstline, new_lastline, false)
+ highlight_buffer(buf, ns, lines, firstline, BUFFER_OPTIONS[buf])
+ end,
+ on_detach = function()
+ BUFFER_OPTIONS[buf] = nil
+ end,
+ })
end
--- Stop highlighting the current buffer.
-- @tparam[opt=0|nil] integer buf A value of 0 or nil implies the current buffer.
-- @tparam[opt=DEFAULT_NAMESPACE] integer ns the namespace id.
local function detach_from_buffer(buf, ns)
- if buf == 0 or buf == nil then
- buf = nvim_get_current_buf()
- end
- nvim_buf_clear_namespace(buf, ns or DEFAULT_NAMESPACE, 0, -1)
- BUFFER_OPTIONS[buf] = nil
+ if buf == 0 or buf == nil then
+ buf = nvim_get_current_buf()
+ end
+ nvim_buf_clear_namespace(buf, ns or DEFAULT_NAMESPACE, 0, -1)
+ BUFFER_OPTIONS[buf] = nil
end
--- Easy to use function if you want the full setup without fine grained control.
@@ -728,84 +725,84 @@ end
-- @tparam[opt] {[string]=string} default_options Default options to apply for the filetypes enable.
-- @usage require'colorizer'.setup()
local function setup(filetypes, user_default_options)
- if not nvim.o.termguicolors then
- nvim.err_writeln "&termguicolors must be set"
+ if not nvim.o.termguicolors then
+ nvim.err_writeln "&termguicolors must be set"
+ return
+ end
+ FILETYPE_OPTIONS = {}
+ SETUP_SETTINGS = {
+ exclusions = {},
+ default_options = merge(DEFAULT_OPTIONS, user_default_options or {}),
+ }
+ -- Initialize this AFTER setting COLOR_NAME_SETTINGS
+ initialize_trie()
+ function COLORIZER_SETUP_HOOK()
+ local filetype = nvim.bo.filetype
+ if SETUP_SETTINGS.exclusions[filetype] then
return
- end
- FILETYPE_OPTIONS = {}
- SETUP_SETTINGS = {
- exclusions = {},
- default_options = merge(DEFAULT_OPTIONS, user_default_options or {}),
- }
- -- Initialize this AFTER setting COLOR_NAME_SETTINGS
- initialize_trie()
- function COLORIZER_SETUP_HOOK()
- local filetype = nvim.bo.filetype
- if SETUP_SETTINGS.exclusions[filetype] then
- return
+ end
+ local options = FILETYPE_OPTIONS[filetype] or SETUP_SETTINGS.default_options
+ attach_to_buffer(nvim_get_current_buf(), options)
+ end
+ nvim.ex.augroup "ColorizerSetup"
+ nvim.ex.autocmd_()
+ if not filetypes then
+ nvim.ex.autocmd "FileType * lua COLORIZER_SETUP_HOOK()"
+ else
+ for k, v in pairs(filetypes) do
+ local filetype
+ local options = SETUP_SETTINGS.default_options
+ if type(k) == "string" then
+ filetype = k
+ if type(v) ~= "table" then
+ nvim.err_writeln("colorizer: Invalid option type for filetype " .. filetype)
+ else
+ options = merge(SETUP_SETTINGS.default_options, v)
+ assert(
+ HIGHLIGHT_MODE_NAMES[options.mode or "background"],
+ "colorizer: Invalid mode: " .. tostring(options.mode)
+ )
+ end
+ else
+ filetype = v
end
- local options = FILETYPE_OPTIONS[filetype] or SETUP_SETTINGS.default_options
- attach_to_buffer(nvim_get_current_buf(), options)
- end
- nvim.ex.augroup "ColorizerSetup"
- nvim.ex.autocmd_()
- if not filetypes then
- nvim.ex.autocmd "FileType * lua COLORIZER_SETUP_HOOK()"
- else
- for k, v in pairs(filetypes) do
- local filetype
- local options = SETUP_SETTINGS.default_options
- if type(k) == "string" then
- filetype = k
- if type(v) ~= "table" then
- nvim.err_writeln("colorizer: Invalid option type for filetype " .. filetype)
- else
- options = merge(SETUP_SETTINGS.default_options, v)
- assert(
- HIGHLIGHT_MODE_NAMES[options.mode or "background"],
- "colorizer: Invalid mode: " .. tostring(options.mode)
- )
- end
- else
- filetype = v
- end
- -- Exclude
- if filetype:sub(1, 1) == "!" then
- SETUP_SETTINGS.exclusions[filetype:sub(2)] = true
- else
- FILETYPE_OPTIONS[filetype] = options
- -- TODO What's the right mode for this? BufEnter?
- nvim.ex.autocmd("FileType", filetype, "lua COLORIZER_SETUP_HOOK()")
- end
+ -- Exclude
+ if filetype:sub(1, 1) == "!" then
+ SETUP_SETTINGS.exclusions[filetype:sub(2)] = true
+ else
+ FILETYPE_OPTIONS[filetype] = options
+ -- TODO What's the right mode for this? BufEnter?
+ nvim.ex.autocmd("FileType", filetype, "lua COLORIZER_SETUP_HOOK()")
end
- end
- nvim.ex.augroup "END"
+ end
+ end
+ nvim.ex.augroup "END"
end
--- Reload all of the currently active highlighted buffers.
local function reload_all_buffers()
- for buf, buffer_options in pairs(BUFFER_OPTIONS) do
- attach_to_buffer(buf)
- end
+ for buf, buffer_options in pairs(BUFFER_OPTIONS) do
+ attach_to_buffer(buf)
+ end
end
--- Return the currently active buffer options.
-- @tparam[opt=0|nil] integer buf A value of 0 or nil implies the current buffer.
local function get_buffer_options(buf)
- if buf == 0 or buf == nil then
- buf = nvim_get_current_buf()
- end
- return merge({}, BUFFER_OPTIONS[buf])
+ if buf == 0 or buf == nil then
+ buf = nvim_get_current_buf()
+ end
+ return merge({}, BUFFER_OPTIONS[buf])
end
--- @export
return {
- DEFAULT_NAMESPACE = DEFAULT_NAMESPACE,
- setup = setup,
- is_buffer_attached = is_buffer_attached,
- attach_to_buffer = attach_to_buffer,
- detach_from_buffer = detach_from_buffer,
- highlight_buffer = highlight_buffer,
- reload_all_buffers = reload_all_buffers,
- get_buffer_options = get_buffer_options,
+ DEFAULT_NAMESPACE = DEFAULT_NAMESPACE,
+ setup = setup,
+ is_buffer_attached = is_buffer_attached,
+ attach_to_buffer = attach_to_buffer,
+ detach_from_buffer = detach_from_buffer,
+ highlight_buffer = highlight_buffer,
+ reload_all_buffers = reload_all_buffers,
+ get_buffer_options = get_buffer_options,
}
diff --git a/lua/colorizer/nvim.lua b/lua/colorizer/nvim.lua
index c51d2ca..3d83bd0 100644
--- a/lua/colorizer/nvim.lua
+++ b/lua/colorizer/nvim.lua
@@ -3,45 +3,102 @@
-- Equivalent to `echo vim.inspect(...)`
local function nvim_print(...)
- if select("#", ...) == 1 then
- vim.api.nvim_out_write(vim.inspect((...)))
- else
- vim.api.nvim_out_write(vim.inspect {...})
- end
- vim.api.nvim_out_write("\n")
+ if select("#", ...) == 1 then
+ vim.api.nvim_out_write(vim.inspect((...)))
+ else
+ vim.api.nvim_out_write(vim.inspect { ... })
+ end
+ vim.api.nvim_out_write "\n"
end
--- Equivalent to `echo` EX command
local function nvim_echo(...)
- for i = 1, select("#", ...) do
- local part = select(i, ...)
- vim.api.nvim_out_write(tostring(part))
- -- vim.api.nvim_out_write("\n")
- vim.api.nvim_out_write(" ")
- end
- vim.api.nvim_out_write("\n")
+ for i = 1, select("#", ...) do
+ local part = select(i, ...)
+ vim.api.nvim_out_write(tostring(part))
+ -- vim.api.nvim_out_write("\n")
+ vim.api.nvim_out_write " "
+ end
+ vim.api.nvim_out_write "\n"
end
local window_options = {
- arab = true; arabic = true; breakindent = true; breakindentopt = true;
- bri = true; briopt = true; cc = true; cocu = true;
- cole = true; colorcolumn = true; concealcursor = true; conceallevel = true;
- crb = true; cuc = true; cul = true; cursorbind = true;
- cursorcolumn = true; cursorline = true; diff = true; fcs = true;
- fdc = true; fde = true; fdi = true; fdl = true;
- fdm = true; fdn = true; fdt = true; fen = true;
- fillchars = true; fml = true; fmr = true; foldcolumn = true;
- foldenable = true; foldexpr = true; foldignore = true; foldlevel = true;
- foldmarker = true; foldmethod = true; foldminlines = true; foldnestmax = true;
- foldtext = true; lbr = true; lcs = true; linebreak = true;
- list = true; listchars = true; nu = true; number = true;
- numberwidth = true; nuw = true; previewwindow = true; pvw = true;
- relativenumber = true; rightleft = true; rightleftcmd = true; rl = true;
- rlc = true; rnu = true; scb = true; scl = true;
- scr = true; scroll = true; scrollbind = true; signcolumn = true;
- spell = true; statusline = true; stl = true; wfh = true;
- wfw = true; winbl = true; winblend = true; winfixheight = true;
- winfixwidth = true; winhighlight = true; winhl = true; wrap = true;
+ arab = true,
+ arabic = true,
+ breakindent = true,
+ breakindentopt = true,
+ bri = true,
+ briopt = true,
+ cc = true,
+ cocu = true,
+ cole = true,
+ colorcolumn = true,
+ concealcursor = true,
+ conceallevel = true,
+ crb = true,
+ cuc = true,
+ cul = true,
+ cursorbind = true,
+ cursorcolumn = true,
+ cursorline = true,
+ diff = true,
+ fcs = true,
+ fdc = true,
+ fde = true,
+ fdi = true,
+ fdl = true,
+ fdm = true,
+ fdn = true,
+ fdt = true,
+ fen = true,
+ fillchars = true,
+ fml = true,
+ fmr = true,
+ foldcolumn = true,
+ foldenable = true,
+ foldexpr = true,
+ foldignore = true,
+ foldlevel = true,
+ foldmarker = true,
+ foldmethod = true,
+ foldminlines = true,
+ foldnestmax = true,
+ foldtext = true,
+ lbr = true,
+ lcs = true,
+ linebreak = true,
+ list = true,
+ listchars = true,
+ nu = true,
+ number = true,
+ numberwidth = true,
+ nuw = true,
+ previewwindow = true,
+ pvw = true,
+ relativenumber = true,
+ rightleft = true,
+ rightleftcmd = true,
+ rl = true,
+ rlc = true,
+ rnu = true,
+ scb = true,
+ scl = true,
+ scr = true,
+ scroll = true,
+ scrollbind = true,
+ signcolumn = true,
+ spell = true,
+ statusline = true,
+ stl = true,
+ wfh = true,
+ wfw = true,
+ winbl = true,
+ winblend = true,
+ winfixheight = true,
+ winfixwidth = true,
+ winhighlight = true,
+ winhl = true,
+ wrap = true,
}
-- `nvim.$method(...)` redirects to `nvim.api.nvim_$method(...)`
@@ -51,143 +108,144 @@ local window_options = {
-- `nvim.echo(...)` is approximately `echo table.concat({...}, '\n')`
-- Both methods cache the inital lookup in the metatable, but there is a small overhead regardless.
return setmetatable({
- print = nvim_print;
- echo = nvim_echo;
- fn = setmetatable({}, {
- __index = function(self, k)
- local mt = getmetatable(self)
- local x = mt[k]
- if x ~= nil then
- return x
- end
- local f = function(...) return vim.api.nvim_call_function(k, {...}) end
- mt[k] = f
- return f
- end
- });
- buf = setmetatable({
- }, {
- __index = function(self, k)
- local mt = getmetatable(self)
- local x = mt[k]
- if x ~= nil then return x end
- local f
- if k == 'line' then
- f = function()
- local pos = vim.api.nvim_win_get_cursor(0)
- return vim.api.nvim_buf_get_lines(0, pos[1]-1, pos[1], 'line')[1]
- end
- elseif k == 'nr' then
- f = vim.api.nvim_get_current_buf
- end
- mt[k] = f
- return f
- end
- });
- ex = setmetatable({}, {
- __index = function(self, k)
- local mt = getmetatable(self)
- local x = mt[k]
- if x ~= nil then
- return x
- end
- local command = k:gsub("_$", "!")
- local f = function(...)
- return vim.api.nvim_command(table.concat(vim.tbl_flatten {command, ...}, " "))
- end
- mt[k] = f
- return f
- end
- });
- g = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_get_var(k)
- end;
- __newindex = function(_, k, v)
- if v == nil then
- return vim.api.nvim_del_var(k)
- else
- return vim.api.nvim_set_var(k, v)
- end
- end;
- });
- v = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_get_vvar(k)
- end;
- __newindex = function(_, k, v)
- return vim.api.nvim_set_vvar(k, v)
- end
- });
- b = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_buf_get_var(0, k)
- end;
- __newindex = function(_, k, v)
- if v == nil then
- return vim.api.nvim_buf_del_var(0, k)
- else
- return vim.api.nvim_buf_set_var(0, k, v)
- end
- end
- });
- w = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_win_get_var(0, k)
- end;
- __newindex = function(_, k, v)
- if v == nil then
- return vim.api.nvim_win_del_var(0, k)
- else
- return vim.api.nvim_win_set_var(0, k, v)
- end
- end
- });
- o = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_get_option(k)
- end;
- __newindex = function(_, k, v)
- return vim.api.nvim_set_option(k, v)
- end
- });
- -- TODO add warning if you try to use a window option here?
- bo = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_buf_get_option(0, k)
- end;
- __newindex = function(_, k, v)
- return vim.api.nvim_buf_set_option(0, k, v)
- end
- });
- wo = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_win_get_option(0, k)
- end;
- __newindex = function(_, k, v)
- -- passing v == nil will clear the value, just like above.
- return vim.api.nvim_win_set_option(0, k, v)
- end
- });
- env = setmetatable({}, {
- __index = function(_, k)
- return vim.api.nvim_call_function('getenv', {k})
- end;
- __newindex = function(_, k, v)
- return vim.api.nvim_call_function('setenv', {k, v})
- end
- });
+ print = nvim_print,
+ echo = nvim_echo,
+ fn = setmetatable({}, {
+ __index = function(self, k)
+ local mt = getmetatable(self)
+ local x = mt[k]
+ if x ~= nil then
+ return x
+ end
+ local f = function(...)
+ return vim.api.nvim_call_function(k, { ... })
+ end
+ mt[k] = f
+ return f
+ end,
+ }),
+ buf = setmetatable({}, {
+ __index = function(self, k)
+ local mt = getmetatable(self)
+ local x = mt[k]
+ if x ~= nil then
+ return x
+ end
+ local f
+ if k == "line" then
+ f = function()
+ local pos = vim.api.nvim_win_get_cursor(0)
+ return vim.api.nvim_buf_get_lines(0, pos[1] - 1, pos[1], "line")[1]
+ end
+ elseif k == "nr" then
+ f = vim.api.nvim_get_current_buf
+ end
+ mt[k] = f
+ return f
+ end,
+ }),
+ ex = setmetatable({}, {
+ __index = function(self, k)
+ local mt = getmetatable(self)
+ local x = mt[k]
+ if x ~= nil then
+ return x
+ end
+ local command = k:gsub("_$", "!")
+ local f = function(...)
+ return vim.api.nvim_command(table.concat(vim.tbl_flatten { command, ... }, " "))
+ end
+ mt[k] = f
+ return f
+ end,
+ }),
+ g = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_get_var(k)
+ end,
+ __newindex = function(_, k, v)
+ if v == nil then
+ return vim.api.nvim_del_var(k)
+ else
+ return vim.api.nvim_set_var(k, v)
+ end
+ end,
+ }),
+ v = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_get_vvar(k)
+ end,
+ __newindex = function(_, k, v)
+ return vim.api.nvim_set_vvar(k, v)
+ end,
+ }),
+ b = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_buf_get_var(0, k)
+ end,
+ __newindex = function(_, k, v)
+ if v == nil then
+ return vim.api.nvim_buf_del_var(0, k)
+ else
+ return vim.api.nvim_buf_set_var(0, k, v)
+ end
+ end,
+ }),
+ w = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_win_get_var(0, k)
+ end,
+ __newindex = function(_, k, v)
+ if v == nil then
+ return vim.api.nvim_win_del_var(0, k)
+ else
+ return vim.api.nvim_win_set_var(0, k, v)
+ end
+ end,
+ }),
+ o = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_get_option(k)
+ end,
+ __newindex = function(_, k, v)
+ return vim.api.nvim_set_option(k, v)
+ end,
+ }),
+ -- TODO add warning if you try to use a window option here?
+ bo = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_buf_get_option(0, k)
+ end,
+ __newindex = function(_, k, v)
+ return vim.api.nvim_buf_set_option(0, k, v)
+ end,
+ }),
+ wo = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_win_get_option(0, k)
+ end,
+ __newindex = function(_, k, v)
+ -- passing v == nil will clear the value, just like above.
+ return vim.api.nvim_win_set_option(0, k, v)
+ end,
+ }),
+ env = setmetatable({}, {
+ __index = function(_, k)
+ return vim.api.nvim_call_function("getenv", { k })
+ end,
+ __newindex = function(_, k, v)
+ return vim.api.nvim_call_function("setenv", { k, v })
+ end,
+ }),
}, {
- __index = function(self, k)
- local mt = getmetatable(self)
- local x = mt[k]
- if x ~= nil then
- return x
- end
- local f = vim.api['nvim_'..k]
- mt[k] = f
- return f
- end
+ __index = function(self, k)
+ local mt = getmetatable(self)
+ local x = mt[k]
+ if x ~= nil then
+ return x
+ end
+ local f = vim.api["nvim_" .. k]
+ mt[k] = f
+ return f
+ end,
})
-
-
diff --git a/lua/colorizer/trie.lua b/lua/colorizer/trie.lua
index 21794ef..21ea543 100644
--- a/lua/colorizer/trie.lua
+++ b/lua/colorizer/trie.lua
@@ -13,7 +13,7 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-local ffi = require 'ffi'
+local ffi = require "ffi"
ffi.cdef [[
struct Trie {
@@ -24,219 +24,227 @@ void *malloc(size_t size);
void free(void *ptr);
]]
-local Trie_t = ffi.typeof('struct Trie')
-local Trie_ptr_t = ffi.typeof('$ *', Trie_t)
+local Trie_t = ffi.typeof "struct Trie"
+local Trie_ptr_t = ffi.typeof("$ *", Trie_t)
local Trie_size = ffi.sizeof(Trie_t)
local function trie_create()
- local ptr = ffi.C.malloc(Trie_size)
- ffi.fill(ptr, Trie_size)
- return ffi.cast(Trie_ptr_t, ptr)
+ local ptr = ffi.C.malloc(Trie_size)
+ ffi.fill(ptr, Trie_size)
+ return ffi.cast(Trie_ptr_t, ptr)
end
local function trie_destroy(trie)
- if trie == nil then
- return
- end
- for i = 0, 61 do
- local child = trie.character[i]
- if child ~= nil then
- trie_destroy(child)
- end
- end
- ffi.C.free(trie)
+ if trie == nil then
+ return
+ end
+ for i = 0, 61 do
+ local child = trie.character[i]
+ if child ~= nil then
+ trie_destroy(child)
+ end
+ end
+ ffi.C.free(trie)
end
-local INDEX_LOOKUP_TABLE = ffi.new 'uint8_t[256]'
-local CHAR_LOOKUP_TABLE = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
+local INDEX_LOOKUP_TABLE = ffi.new "uint8_t[256]"
+local CHAR_LOOKUP_TABLE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
do
- local b = string.byte
- for i = 0, 255 do
- if i >= b'0' and i <= b'9' then
- INDEX_LOOKUP_TABLE[i] = i - b'0'
- elseif i >= b'A' and i <= b'Z' then
- INDEX_LOOKUP_TABLE[i] = i - b'A' + 10
- elseif i >= b'a' and i <= b'z' then
- INDEX_LOOKUP_TABLE[i] = i - b'a' + 10 + 26
- else
- INDEX_LOOKUP_TABLE[i] = 255
- end
- end
+ local b = string.byte
+ for i = 0, 255 do
+ if i >= b "0" and i <= b "9" then
+ INDEX_LOOKUP_TABLE[i] = i - b "0"
+ elseif i >= b "A" and i <= b "Z" then
+ INDEX_LOOKUP_TABLE[i] = i - b "A" + 10
+ elseif i >= b "a" and i <= b "z" then
+ INDEX_LOOKUP_TABLE[i] = i - b "a" + 10 + 26
+ else
+ INDEX_LOOKUP_TABLE[i] = 255
+ end
+ end
end
local function trie_insert(trie, value)
- if trie == nil then return false end
- local node = trie
- for i = 1, #value do
- local index = INDEX_LOOKUP_TABLE[value:byte(i)]
- if index == 255 then
- return false
- end
- if node.character[index] == nil then
- node.character[index] = trie_create()
- end
- node = node.character[index]
- end
- node.is_leaf = true
- return node, trie
+ if trie == nil then
+ return false
+ end
+ local node = trie
+ for i = 1, #value do
+ local index = INDEX_LOOKUP_TABLE[value:byte(i)]
+ if index == 255 then
+ return false
+ end
+ if node.character[index] == nil then
+ node.character[index] = trie_create()
+ end
+ node = node.character[index]
+ end
+ node.is_leaf = true
+ return node, trie
end
local function trie_search(trie, value, start)
- if trie == nil then return false end
- local node = trie
- for i = (start or 1), #value do
- local index = INDEX_LOOKUP_TABLE[value:byte(i)]
- if index == 255 then
- return
- end
- local child = node.character[index]
- if child == nil then
- return false
- end
- node = child
- end
- return node.is_leaf
+ if trie == nil then
+ return false
+ end
+ local node = trie
+ for i = (start or 1), #value do
+ local index = INDEX_LOOKUP_TABLE[value:byte(i)]
+ if index == 255 then
+ return
+ end
+ local child = node.character[index]
+ if child == nil then
+ return false
+ end
+ node = child
+ end
+ return node.is_leaf
end
local function trie_longest_prefix(trie, value, start)
- if trie == nil then return false end
- -- insensitive = insensitive and 0x20 or 0
- start = start or 1
- local node = trie
- local last_i = nil
- for i = start, #value do
- local index = INDEX_LOOKUP_TABLE[value:byte(i)]
--- local index = INDEX_LOOKUP_TABLE[bor(insensitive, value:byte(i))]
- if index == 255 then
- break
- end
- local child = node.character[index]
- if child == nil then
- break
- end
- if child.is_leaf then
- last_i = i
- end
- node = child
- end
- if last_i then
- -- Avoid a copy if the whole string is a match.
- if start == 1 and last_i == #value then
- return value
- else
- return value:sub(start, last_i)
- end
- end
+ if trie == nil then
+ return false
+ end
+ -- insensitive = insensitive and 0x20 or 0
+ start = start or 1
+ local node = trie
+ local last_i = nil
+ for i = start, #value do
+ local index = INDEX_LOOKUP_TABLE[value:byte(i)]
+ -- local index = INDEX_LOOKUP_TABLE[bor(insensitive, value:byte(i))]
+ if index == 255 then
+ break
+ end
+ local child = node.character[index]
+ if child == nil then
+ break
+ end
+ if child.is_leaf then
+ last_i = i
+ end
+ node = child
+ end
+ if last_i then
+ -- Avoid a copy if the whole string is a match.
+ if start == 1 and last_i == #value then
+ return value
+ else
+ return value:sub(start, last_i)
+ end
+ end
end
local function trie_extend(trie, t)
- assert(type(t) == 'table')
- for _, v in ipairs(t) do
- trie_insert(trie, v)
- end
+ assert(type(t) == "table")
+ for _, v in ipairs(t) do
+ trie_insert(trie, v)
+ end
end
--- Printing utilities
local function index_to_char(index)
- if index < 0 or index > 61 then return end
- return CHAR_LOOKUP_TABLE:sub(index+1, index+1)
+ if index < 0 or index > 61 then
+ return
+ end
+ return CHAR_LOOKUP_TABLE:sub(index + 1, index + 1)
end
local function trie_as_table(trie)
- if trie == nil then
- return nil
- end
- local children = {}
- for i = 0, 61 do
- local child = trie.character[i]
- if child ~= nil then
- local child_table = trie_as_table(child)
- child_table.c = index_to_char(i)
- table.insert(children, child_table)
- end
- end
- return {
- is_leaf = trie.is_leaf;
- children = children;
- }
+ if trie == nil then
+ return nil
+ end
+ local children = {}
+ for i = 0, 61 do
+ local child = trie.character[i]
+ if child ~= nil then
+ local child_table = trie_as_table(child)
+ child_table.c = index_to_char(i)
+ table.insert(children, child_table)
+ end
+ end
+ return {
+ is_leaf = trie.is_leaf,
+ children = children,
+ }
end
local function print_trie_table(s)
- local mark
- if not s then
- return {'nil'}
- end
- if s.c then
- if s.is_leaf then
- mark = s.c.."*"
- else
- mark = s.c.."─"
- end
- else
- mark = "├─"
- end
- if #s.children == 0 then
- return {mark}
- end
- local lines = {}
- for _, child in ipairs(s.children) do
- local child_lines = print_trie_table(child, thicc)
- for _, child_line in ipairs(child_lines) do
- table.insert(lines, child_line)
- end
- end
- local child_count = 0
- for i, line in ipairs(lines) do
- local line_parts = {}
- if line:match("^%w") then
- child_count = child_count + 1
- if i == 1 then
- line_parts = {mark}
- elseif i == #lines or child_count == #s.children then
- line_parts = {"└─"}
- else
- line_parts = {"├─"}
- end
- else
- if i == 1 then
- line_parts = {mark}
- elseif #s.children > 1 and child_count ~= #s.children then
- line_parts = {"│ "}
- else
- line_parts = {" "}
- end
- end
- table.insert(line_parts, line)
- lines[i] = table.concat(line_parts)
- end
- return lines
+ local mark
+ if not s then
+ return { "nil" }
+ end
+ if s.c then
+ if s.is_leaf then
+ mark = s.c .. "*"
+ else
+ mark = s.c .. "─"
+ end
+ else
+ mark = "├─"
+ end
+ if #s.children == 0 then
+ return { mark }
+ end
+ local lines = {}
+ for _, child in ipairs(s.children) do
+ local child_lines = print_trie_table(child, thicc)
+ for _, child_line in ipairs(child_lines) do
+ table.insert(lines, child_line)
+ end
+ end
+ local child_count = 0
+ for i, line in ipairs(lines) do
+ local line_parts = {}
+ if line:match "^%w" then
+ child_count = child_count + 1
+ if i == 1 then
+ line_parts = { mark }
+ elseif i == #lines or child_count == #s.children then
+ line_parts = { "└─" }
+ else
+ line_parts = { "├─" }
+ end
+ else
+ if i == 1 then
+ line_parts = { mark }
+ elseif #s.children > 1 and child_count ~= #s.children then
+ line_parts = { "│ " }
+ else
+ line_parts = { " " }
+ end
+ end
+ table.insert(line_parts, line)
+ lines[i] = table.concat(line_parts)
+ end
+ return lines
end
local function trie_to_string(trie)
- if trie == nil then
- return 'nil'
- end
- local as_table = trie_as_table(trie)
- return table.concat(print_trie_table(as_table), '\n')
+ if trie == nil then
+ return "nil"
+ end
+ local as_table = trie_as_table(trie)
+ return table.concat(print_trie_table(as_table), "\n")
end
local Trie_mt = {
- __new = function(_, init)
- local trie = trie_create()
- if type(init) == 'table' then
- trie_extend(trie, init)
- end
- return trie
- end;
- __index = {
- insert = trie_insert;
- search = trie_search;
- longest_prefix = trie_longest_prefix;
- extend = trie_extend;
- };
- __tostring = trie_to_string;
- __gc = trie_destroy;
+ __new = function(_, init)
+ local trie = trie_create()
+ if type(init) == "table" then
+ trie_extend(trie, init)
+ end
+ return trie
+ end,
+ __index = {
+ insert = trie_insert,
+ search = trie_search,
+ longest_prefix = trie_longest_prefix,
+ extend = trie_extend,
+ },
+ __tostring = trie_to_string,
+ __gc = trie_destroy,
}
-return ffi.metatype('struct Trie', Trie_mt)
+return ffi.metatype("struct Trie", Trie_mt)
diff --git a/test/print-trie.lua b/test/print-trie.lua
index 2ec1322..7575b5c 100644
--- a/test/print-trie.lua
+++ b/test/print-trie.lua
@@ -1,62 +1,62 @@
-- TODO this is kinda shitty
-local function dirname(str,sep)
- sep=sep or'/'
- return str:match("(.*"..sep..")")
+local function dirname(str, sep)
+ sep = sep or "/"
+ return str:match("(.*" .. sep .. ")")
end
local script_dir = dirname(arg[0])
-package.path = script_dir.."/../lua/?.lua;"..package.path
+package.path = script_dir .. "/../lua/?.lua;" .. package.path
-local Trie = require 'trie'
-local nvim = require 'nvim'
+local Trie = require "trie"
+local nvim = require "nvim"
local function print_color_trie()
- local tohex = bit.tohex
- local min, max = math.min, math.max
+ local tohex = bit.tohex
+ local min, max = math.min, math.max
- local COLOR_NAME_SETTINGS = {
- lowercase = false;
- strip_digits = true;
- }
- local COLOR_MAP = {}
- local COLOR_TRIE = Trie()
- for k, v in pairs(nvim.get_color_map()) do
- if not (COLOR_NAME_SETTINGS.strip_digits and k:match("%d+$")) then
- COLOR_NAME_MINLEN = COLOR_NAME_MINLEN and min(#k, COLOR_NAME_MINLEN) or #k
- COLOR_NAME_MAXLEN = COLOR_NAME_MAXLEN and max(#k, COLOR_NAME_MAXLEN) or #k
- COLOR_MAP[k] = tohex(v, 6)
- COLOR_TRIE:insert(k)
- if COLOR_NAME_SETTINGS.lowercase then
- local lowercase = k:lower()
- COLOR_MAP[lowercase] = tohex(v, 6)
- COLOR_TRIE:insert(lowercase)
- end
- end
- end
- print(COLOR_TRIE)
+ local COLOR_NAME_SETTINGS = {
+ lowercase = false,
+ strip_digits = true,
+ }
+ local COLOR_MAP = {}
+ local COLOR_TRIE = Trie()
+ for k, v in pairs(nvim.get_color_map()) do
+ if not (COLOR_NAME_SETTINGS.strip_digits and k:match "%d+$") then
+ COLOR_NAME_MINLEN = COLOR_NAME_MINLEN and min(#k, COLOR_NAME_MINLEN) or #k
+ COLOR_NAME_MAXLEN = COLOR_NAME_MAXLEN and max(#k, COLOR_NAME_MAXLEN) or #k
+ COLOR_MAP[k] = tohex(v, 6)
+ COLOR_TRIE:insert(k)
+ if COLOR_NAME_SETTINGS.lowercase then
+ local lowercase = k:lower()
+ COLOR_MAP[lowercase] = tohex(v, 6)
+ COLOR_TRIE:insert(lowercase)
+ end
+ end
+ end
+ print(COLOR_TRIE)
end
local trie = Trie {
- "cat";
- "car";
- "celtic";
- "carb";
- "carb0";
- "CART0";
- "CaRT0";
- "Cart0";
- "931";
- "191";
- "121";
- "cardio";
- "call";
- "calcium";
- "calciur";
- "carry";
- "dog";
- "catdog";
+ "cat",
+ "car",
+ "celtic",
+ "carb",
+ "carb0",
+ "CART0",
+ "CaRT0",
+ "Cart0",
+ "931",
+ "191",
+ "121",
+ "cardio",
+ "call",
+ "calcium",
+ "calciur",
+ "carry",
+ "dog",
+ "catdog",
}
print(trie)
-print("catdo", trie:longest_prefix("catdo"))
-print("catastrophic", trie:longest_prefix("catastrophic"))
+print("catdo", trie:longest_prefix "catdo")
+print("catastrophic", trie:longest_prefix "catastrophic")