mirror of
https://github.com/norcalli/nvim-colorizer.lua.git
synced 2026-09-10 07:06:14 -04:00
Add nil checks / refactor bufnr, ns_id parameters (#90)
* chore: adds nil checks and diagnostic ignore hints * ref: use buffer optiontype as key * ref: use bufnr and ns_id to keep in line with neovim api variable naming scheme * chore: creates test for tailwind * ref: use bufnr parameter for buffer id
This commit is contained in:
parent
58bbb51898
commit
e614ff5c26
|
|
@ -67,7 +67,7 @@ local merge = utils.merge
|
|||
local api = vim.api
|
||||
local augroup = api.nvim_create_augroup
|
||||
local autocmd = api.nvim_create_autocmd
|
||||
local buf_get_option = api.nvim_buf_get_option
|
||||
local buf_get_option = api.nvim_get_option_value
|
||||
local clear_namespace = api.nvim_buf_clear_namespace
|
||||
local current_buf = api.nvim_get_current_buf
|
||||
|
||||
|
|
@ -178,25 +178,20 @@ local USER_DEFAULT_OPTIONS = {
|
|||
always_update = false,
|
||||
}
|
||||
|
||||
local OPTIONS = { buf = {}, file = {} }
|
||||
local OPTIONS = { buftype = {}, filetype = {} }
|
||||
local SETUP_SETTINGS = {
|
||||
exclusions = { buf = {}, file = {} },
|
||||
all = { file = false, buf = false },
|
||||
exclusions = { buftype = {}, filetype = {} },
|
||||
all = { buftype = false, filetype = false },
|
||||
default_options = USER_DEFAULT_OPTIONS,
|
||||
}
|
||||
|
||||
--- Make new buffer Configuration
|
||||
---@param buf number: buffer number
|
||||
---@param typ string|nil: "buf" or "file" - The type of buffer option
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
---@param bo_type 'buftype'|'filetype': The type of buffer option
|
||||
---@return table
|
||||
local function new_buffer_options(buf, typ)
|
||||
local value
|
||||
if typ == "buf" then
|
||||
value = buf_get_option(buf, "buftype")
|
||||
else
|
||||
value = buf_get_option(buf, "filetype")
|
||||
end
|
||||
return OPTIONS.file[value] or SETUP_SETTINGS.default_options
|
||||
local function new_buffer_options(bufnr, bo_type)
|
||||
local value = buf_get_option(bo_type, { buf = bufnr })
|
||||
return OPTIONS.filetype[value] or SETUP_SETTINGS.default_options
|
||||
end
|
||||
|
||||
--- Parse buffer Configuration and convert aliases to normal values
|
||||
|
|
@ -245,15 +240,15 @@ local function parse_buffer_options(options)
|
|||
end
|
||||
|
||||
--- Check if attached to a buffer.
|
||||
---@param buf number|nil: A value of 0 implies the current buffer.
|
||||
---@param bufnr number|nil: A value of 0 implies the current buffer.
|
||||
---@return number|nil: if attached to the buffer, false otherwise.
|
||||
---@see colorizer.buffer.highlight
|
||||
function colorizer.is_buffer_attached(buf)
|
||||
if buf == 0 or buf == nil then
|
||||
buf = current_buf()
|
||||
function colorizer.is_buffer_attached(bufnr)
|
||||
if bufnr == 0 or not bufnr then
|
||||
bufnr = current_buf()
|
||||
else
|
||||
if not api.nvim_buf_is_valid(buf) then
|
||||
BUFFER_LOCAL[buf], BUFFER_OPTIONS[buf] = nil, nil
|
||||
if not api.nvim_buf_is_valid(bufnr) then
|
||||
BUFFER_LOCAL[bufnr], BUFFER_OPTIONS[bufnr] = nil, nil
|
||||
return
|
||||
end
|
||||
end
|
||||
|
|
@ -261,72 +256,61 @@ function colorizer.is_buffer_attached(buf)
|
|||
local au = api.nvim_get_autocmds {
|
||||
group = AUGROUP_ID,
|
||||
event = { "WinScrolled", "TextChanged", "TextChangedI", "TextChangedP" },
|
||||
buffer = buf,
|
||||
buffer = bufnr,
|
||||
}
|
||||
if not BUFFER_OPTIONS[buf] or vim.tbl_isempty(au) then
|
||||
if not BUFFER_OPTIONS[bufnr] or vim.tbl_isempty(au) then
|
||||
return
|
||||
end
|
||||
|
||||
return buf
|
||||
return bufnr
|
||||
end
|
||||
|
||||
--- Stop highlighting the current buffer.
|
||||
---@param buf number|nil: buf A value of 0 or nil implies the current buffer.
|
||||
---@param ns number|nil: ns the namespace id, if not given DEFAULT_NAMESPACE is used
|
||||
function colorizer.detach_from_buffer(buf, ns)
|
||||
buf = colorizer.is_buffer_attached(buf)
|
||||
if not buf then
|
||||
---@param bufnr number|nil: buffer number (0 for current)
|
||||
---@param ns_id number|nil: namespace id. default is "colorizer", created with vim.api.nvim_create_namespace
|
||||
function colorizer.detach_from_buffer(bufnr, ns_id)
|
||||
bufnr = colorizer.is_buffer_attached(bufnr)
|
||||
if not bufnr then
|
||||
return
|
||||
end
|
||||
|
||||
clear_namespace(buf, ns or colorizer.DEFAULT_NAMESPACE, 0, -1)
|
||||
if BUFFER_LOCAL[buf] then
|
||||
for _, namespace in pairs(BUFFER_LOCAL[buf].__detach.ns) do
|
||||
clear_namespace(buf, namespace, 0, -1)
|
||||
clear_namespace(bufnr, ns_id or colorizer.DEFAULT_NAMESPACE, 0, -1)
|
||||
if BUFFER_LOCAL[bufnr] then
|
||||
for _, namespace in pairs(BUFFER_LOCAL[bufnr].__detach.ns_id) do
|
||||
clear_namespace(bufnr, namespace, 0, -1)
|
||||
end
|
||||
|
||||
for _, f in pairs(BUFFER_LOCAL[buf].__detach.functions) do
|
||||
for _, f in pairs(BUFFER_LOCAL[bufnr].__detach.functions) do
|
||||
if type(f) == "function" then
|
||||
f(buf)
|
||||
f(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
for _, id in ipairs(BUFFER_LOCAL[buf].__autocmds or {}) do
|
||||
for _, id in ipairs(BUFFER_LOCAL[bufnr].__autocmds or {}) do
|
||||
pcall(api.nvim_del_autocmd, id)
|
||||
end
|
||||
|
||||
BUFFER_LOCAL[buf].__autocmds = nil
|
||||
BUFFER_LOCAL[buf].__detach = nil
|
||||
BUFFER_LOCAL[bufnr].__autocmds = nil
|
||||
BUFFER_LOCAL[bufnr].__detach = nil
|
||||
end
|
||||
-- because now the buffer is not visible, so delete its information
|
||||
BUFFER_OPTIONS[buf] = nil
|
||||
BUFFER_OPTIONS[bufnr] = nil
|
||||
end
|
||||
|
||||
---Attach to a buffer and continuously highlight changes.
|
||||
---@param buf integer: A value of 0 implies the current buffer.
|
||||
---@param bufnr number|nil: buffer number (0 for current)
|
||||
---@param options table|nil: Configuration options as described in `setup`
|
||||
---@param typ string|nil: "buf" or "file" - The type of buffer option
|
||||
function colorizer.attach_to_buffer(buf, options, typ)
|
||||
if buf == 0 or buf == nil then
|
||||
buf = current_buf()
|
||||
else
|
||||
if not api.nvim_buf_is_valid(buf) then
|
||||
BUFFER_LOCAL[buf], BUFFER_OPTIONS[buf] = nil, nil
|
||||
return
|
||||
end
|
||||
---@param bo_type 'buftype'|'filetype'|nil: The type of buffer option
|
||||
function colorizer.attach_to_buffer(bufnr, options, bo_type)
|
||||
bufnr = bufnr and bufnr ~= 0 and api.nvim_buf_is_valid(bufnr) and bufnr or current_buf()
|
||||
bo_type = bo_type or "buftype"
|
||||
if not api.nvim_buf_is_valid(bufnr) then
|
||||
BUFFER_LOCAL[bufnr], BUFFER_OPTIONS[bufnr] = nil, nil
|
||||
return
|
||||
end
|
||||
|
||||
-- if the buffer is already attached then grab those options
|
||||
if not options then
|
||||
options = colorizer.get_buffer_options(buf)
|
||||
end
|
||||
|
||||
-- if not make new options
|
||||
if not options then
|
||||
options = new_buffer_options(buf, typ)
|
||||
end
|
||||
|
||||
options = parse_buffer_options(options)
|
||||
-- set options by grabbing existing or creating new options, then parsing
|
||||
options = parse_buffer_options(options or colorizer.get_buffer_options(bufnr) or new_buffer_options(bufnr, bo_type))
|
||||
|
||||
if not buffer_utils.highlight_mode_names[options.mode] then
|
||||
if options.mode ~= nil then
|
||||
|
|
@ -339,20 +323,20 @@ function colorizer.attach_to_buffer(buf, options, typ)
|
|||
options.mode = "background"
|
||||
end
|
||||
|
||||
BUFFER_OPTIONS[buf] = options
|
||||
BUFFER_OPTIONS[bufnr] = options
|
||||
|
||||
BUFFER_LOCAL[buf] = BUFFER_LOCAL[buf] or {}
|
||||
local highlighted, returns = rehighlight_buffer(buf, options)
|
||||
BUFFER_LOCAL[bufnr] = BUFFER_LOCAL[bufnr] or {}
|
||||
local highlighted, returns = rehighlight_buffer(bufnr, options)
|
||||
|
||||
if not highlighted then
|
||||
return
|
||||
end
|
||||
|
||||
BUFFER_LOCAL[buf].__detach = BUFFER_LOCAL[buf].__detach or returns.detach
|
||||
BUFFER_LOCAL[bufnr].__detach = BUFFER_LOCAL[bufnr].__detach or returns.detach
|
||||
|
||||
BUFFER_LOCAL[buf].__init = true
|
||||
BUFFER_LOCAL[bufnr].__init = true
|
||||
|
||||
if BUFFER_LOCAL[buf].__autocmds then
|
||||
if BUFFER_LOCAL[bufnr].__autocmds then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -366,19 +350,19 @@ function colorizer.attach_to_buffer(buf, options, typ)
|
|||
end
|
||||
|
||||
if CURRENT_BUF == 0 then
|
||||
CURRENT_BUF = buf
|
||||
CURRENT_BUF = bufnr
|
||||
end
|
||||
|
||||
if options.always_update then
|
||||
-- attach using lua api so buffer gets updated even when not the current buffer
|
||||
-- completely moving to buf_attach is not possible because it doesn't handle all the text change events
|
||||
vim.api.nvim_buf_attach(buf, false, {
|
||||
vim.api.nvim_buf_attach(bufnr, false, {
|
||||
on_lines = function(_, buffer)
|
||||
-- only reload if the buffer is not the current one
|
||||
if not (CURRENT_BUF == buffer) then
|
||||
-- only reload if it was not disabled using detach_from_buffer
|
||||
if BUFFER_OPTIONS[buf] then
|
||||
rehighlight_buffer(buf, options, BUFFER_LOCAL[buf])
|
||||
if BUFFER_OPTIONS[bufnr] then
|
||||
rehighlight_buffer(bufnr, options, BUFFER_LOCAL[bufnr])
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
|
@ -386,8 +370,8 @@ function colorizer.attach_to_buffer(buf, options, typ)
|
|||
-- only reload if the buffer is not the current one
|
||||
if not (CURRENT_BUF == buffer) then
|
||||
-- only reload if it was not disabled using detach_from_buffer
|
||||
if BUFFER_OPTIONS[buf] then
|
||||
rehighlight_buffer(buf, options, BUFFER_LOCAL[buf])
|
||||
if BUFFER_OPTIONS[bufnr] then
|
||||
rehighlight_buffer(bufnr, options, BUFFER_LOCAL[bufnr])
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
|
@ -396,19 +380,19 @@ function colorizer.attach_to_buffer(buf, options, typ)
|
|||
|
||||
autocmds[#autocmds + 1] = autocmd(text_changed_au, {
|
||||
group = au_group_id,
|
||||
buffer = buf,
|
||||
buffer = bufnr,
|
||||
callback = function(args)
|
||||
CURRENT_BUF = buf
|
||||
CURRENT_BUF = bufnr
|
||||
-- only reload if it was not disabled using detach_from_buffer
|
||||
if BUFFER_OPTIONS[buf] then
|
||||
BUFFER_LOCAL[buf].__event = args.event
|
||||
if BUFFER_OPTIONS[bufnr] then
|
||||
BUFFER_LOCAL[bufnr].__event = args.event
|
||||
if args.event == "TextChanged" or args.event == "InsertLeave" then
|
||||
rehighlight_buffer(buf, options, BUFFER_LOCAL[buf])
|
||||
rehighlight_buffer(bufnr, options, BUFFER_LOCAL[bufnr])
|
||||
else
|
||||
local pos = vim.fn.getpos "."
|
||||
BUFFER_LOCAL[buf].__startline = pos[2] - 1
|
||||
BUFFER_LOCAL[buf].__endline = pos[2]
|
||||
rehighlight_buffer(buf, options, BUFFER_LOCAL[buf], true)
|
||||
BUFFER_LOCAL[bufnr].__startline = pos[2] - 1
|
||||
BUFFER_LOCAL[bufnr].__endline = pos[2]
|
||||
rehighlight_buffer(bufnr, options, BUFFER_LOCAL[bufnr], true)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
|
@ -416,29 +400,29 @@ function colorizer.attach_to_buffer(buf, options, typ)
|
|||
|
||||
autocmds[#autocmds + 1] = autocmd({ "WinScrolled" }, {
|
||||
group = au_group_id,
|
||||
buffer = buf,
|
||||
buffer = bufnr,
|
||||
callback = function(args)
|
||||
-- only reload if it was not disabled using detach_from_buffer
|
||||
if BUFFER_OPTIONS[buf] then
|
||||
BUFFER_LOCAL[buf].__event = args.event
|
||||
rehighlight_buffer(buf, options, BUFFER_LOCAL[buf])
|
||||
if BUFFER_OPTIONS[bufnr] then
|
||||
BUFFER_LOCAL[bufnr].__event = args.event
|
||||
rehighlight_buffer(bufnr, options, BUFFER_LOCAL[bufnr])
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
autocmd({ "BufUnload", "BufDelete" }, {
|
||||
group = au_group_id,
|
||||
buffer = buf,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
if BUFFER_OPTIONS[buf] then
|
||||
colorizer.detach_from_buffer(buf)
|
||||
if BUFFER_OPTIONS[bufnr] then
|
||||
colorizer.detach_from_buffer(bufnr)
|
||||
end
|
||||
BUFFER_LOCAL[buf].__init = nil
|
||||
BUFFER_LOCAL[bufnr].__init = nil
|
||||
end,
|
||||
})
|
||||
|
||||
BUFFER_LOCAL[buf].__autocmds = autocmds
|
||||
BUFFER_LOCAL[buf].__augroup_id = au_group_id
|
||||
BUFFER_LOCAL[bufnr].__autocmds = autocmds
|
||||
BUFFER_LOCAL[bufnr].__augroup_id = au_group_id
|
||||
end
|
||||
|
||||
---Easy to use function if you want the full setup without fine grained control.
|
||||
|
|
@ -477,32 +461,32 @@ function colorizer.setup(config)
|
|||
local user_default_options = conf.user_default_options or conf[2] or {}
|
||||
local buftypes = conf.buftypes or conf[3] or nil
|
||||
|
||||
OPTIONS = { buf = {}, file = {} }
|
||||
OPTIONS = { buftype = {}, filetype = {} }
|
||||
SETUP_SETTINGS = {
|
||||
exclusions = { buf = {}, file = {} },
|
||||
all = { file = false, buf = false },
|
||||
exclusions = { buftype = {}, filetype = {} },
|
||||
all = { buftype = false, filetype = false },
|
||||
default_options = user_default_options,
|
||||
}
|
||||
BUFFER_OPTIONS, BUFFER_LOCAL = {}, {}
|
||||
|
||||
local function COLORIZER_SETUP_HOOK(typ)
|
||||
local function COLORIZER_SETUP_HOOK(bo_type)
|
||||
local filetype = vim.bo.filetype
|
||||
local buftype = vim.bo.buftype
|
||||
local buf = current_buf()
|
||||
BUFFER_LOCAL[buf] = BUFFER_LOCAL[buf] or {}
|
||||
local bufnr = current_buf()
|
||||
BUFFER_LOCAL[bufnr] = BUFFER_LOCAL[bufnr] or {}
|
||||
|
||||
if SETUP_SETTINGS.exclusions.file[filetype] or SETUP_SETTINGS.exclusions.buf[buftype] then
|
||||
if SETUP_SETTINGS.exclusions.filetype[filetype] or SETUP_SETTINGS.exclusions.buftype[buftype] then
|
||||
-- when a filetype is disabled but buftype is enabled, it can Attach in
|
||||
-- some cases, so manually detach
|
||||
if BUFFER_OPTIONS[buf] then
|
||||
colorizer.detach_from_buffer(buf)
|
||||
if BUFFER_OPTIONS[bufnr] then
|
||||
colorizer.detach_from_buffer(bufnr)
|
||||
end
|
||||
BUFFER_LOCAL[buf].__init = nil
|
||||
BUFFER_LOCAL[bufnr].__init = nil
|
||||
return
|
||||
end
|
||||
|
||||
local fopts, bopts, options = OPTIONS[typ][filetype], OPTIONS[typ][buftype], nil
|
||||
if typ == "file" then
|
||||
local fopts, bopts, options = OPTIONS[bo_type][filetype], OPTIONS[bo_type][buftype], nil
|
||||
if bo_type == "filetype" then
|
||||
options = fopts
|
||||
-- if buffer and filetype options both are given, then prefer fileoptions
|
||||
elseif fopts and bopts then
|
||||
|
|
@ -511,7 +495,7 @@ function colorizer.setup(config)
|
|||
options = bopts
|
||||
end
|
||||
|
||||
if not options and not SETUP_SETTINGS.all[typ] then
|
||||
if not options and not SETUP_SETTINGS.all[bo_type] then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -520,15 +504,15 @@ function colorizer.setup(config)
|
|||
-- this should ideally be triggered one time per buffer
|
||||
-- but BufWinEnter also triggers for split formation
|
||||
-- but we don't want that so add a check using local buffer variable
|
||||
if not BUFFER_LOCAL[buf].__init then
|
||||
colorizer.attach_to_buffer(buf, options, typ)
|
||||
if not BUFFER_LOCAL[bufnr].__init then
|
||||
colorizer.attach_to_buffer(bufnr, options, bo_type)
|
||||
end
|
||||
end
|
||||
|
||||
AUGROUP_ID = augroup(AUGROUP_NAME, {})
|
||||
|
||||
local aucmd = { buf = "BufWinEnter", file = "FileType" }
|
||||
local function parse_opts(typ, tbl)
|
||||
local aucmd = { buftype = "BufWinEnter", filetype = "FileType" }
|
||||
local function parse_opts(bo_type, tbl)
|
||||
if type(tbl) == "table" then
|
||||
local list = {}
|
||||
|
||||
|
|
@ -538,7 +522,7 @@ function colorizer.setup(config)
|
|||
if type(k) == "string" then
|
||||
value = k
|
||||
if type(v) ~= "table" then
|
||||
vim.notify("colorizer: Invalid option type for " .. typ .. "type" .. value, 4)
|
||||
vim.notify(string.format("colorizer: Invalid option type for %s", value), 4)
|
||||
else
|
||||
options = merge(SETUP_SETTINGS.default_options, v)
|
||||
end
|
||||
|
|
@ -547,30 +531,30 @@ function colorizer.setup(config)
|
|||
end
|
||||
-- Exclude
|
||||
if value:sub(1, 1) == "!" then
|
||||
SETUP_SETTINGS.exclusions[typ][value:sub(2)] = true
|
||||
SETUP_SETTINGS.exclusions[bo_type][value:sub(2)] = true
|
||||
else
|
||||
OPTIONS[typ][value] = options
|
||||
OPTIONS[bo_type][value] = options
|
||||
if value == "*" then
|
||||
SETUP_SETTINGS.all[typ] = true
|
||||
SETUP_SETTINGS.all[bo_type] = true
|
||||
else
|
||||
table.insert(list, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
autocmd({ aucmd[typ] }, {
|
||||
autocmd({ aucmd[bo_type] }, {
|
||||
group = AUGROUP_ID,
|
||||
pattern = typ == "file" and (SETUP_SETTINGS.all[typ] and "*" or list) or nil,
|
||||
pattern = bo_type == "filetype" and (SETUP_SETTINGS.all[bo_type] and "*" or list) or nil,
|
||||
callback = function()
|
||||
COLORIZER_SETUP_HOOK(typ)
|
||||
COLORIZER_SETUP_HOOK(bo_type)
|
||||
end,
|
||||
})
|
||||
elseif tbl then
|
||||
vim.notify_once(string.format("colorizer: Invalid type for %stypes %s", typ, vim.inspect(tbl)), 4)
|
||||
vim.notify_once(string.format("colorizer: Invalid type for %ss %s", bo_type, vim.inspect(tbl)), 4)
|
||||
end
|
||||
end
|
||||
|
||||
parse_opts("file", filetypes)
|
||||
parse_opts("buf", buftypes)
|
||||
parse_opts("filetype", filetypes)
|
||||
parse_opts("buftype", buftypes)
|
||||
|
||||
autocmd("ColorScheme", {
|
||||
group = AUGROUP_ID,
|
||||
|
|
@ -581,10 +565,10 @@ function colorizer.setup(config)
|
|||
end
|
||||
|
||||
--- Return the currently active buffer options.
|
||||
---@param buf number|nil: Buffer number
|
||||
---@param bufnr number|nil: buffer number (0 for current)
|
||||
---@return table|nil
|
||||
function colorizer.get_buffer_options(buf)
|
||||
local buffer = colorizer.is_buffer_attached(buf)
|
||||
function colorizer.get_buffer_options(bufnr)
|
||||
local buffer = colorizer.is_buffer_attached(bufnr)
|
||||
if buffer then
|
||||
return BUFFER_OPTIONS[buffer]
|
||||
end
|
||||
|
|
@ -592,8 +576,8 @@ end
|
|||
|
||||
--- Reload all of the currently active highlighted buffers.
|
||||
function colorizer.reload_all_buffers()
|
||||
for buf, _ in pairs(BUFFER_OPTIONS) do
|
||||
colorizer.attach_to_buffer(buf, colorizer.get_buffer_options(buf))
|
||||
for bufnr, _ in pairs(BUFFER_OPTIONS) do
|
||||
colorizer.attach_to_buffer(bufnr, colorizer.get_buffer_options(bufnr), "buftype")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ local buf_get_lines = api.nvim_buf_get_lines
|
|||
local create_namespace = api.nvim_create_namespace
|
||||
local clear_namespace = api.nvim_buf_clear_namespace
|
||||
local set_highlight = api.nvim_set_hl
|
||||
local current_buf = api.nvim_get_current_buf
|
||||
|
||||
local color = require "colorizer.color"
|
||||
local color_is_bright = color.is_bright
|
||||
|
|
@ -88,21 +89,21 @@ local function create_highlight(rgb_hex, mode)
|
|||
end
|
||||
|
||||
--- Create highlight and set highlights
|
||||
---@param buf number
|
||||
---@param ns number
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
---@param ns_id number
|
||||
---@param line_start number
|
||||
---@param line_end number
|
||||
---@param data table: table output of `parse_lines`
|
||||
---@param options table: Passed in setup, mainly for `user_default_options`
|
||||
function buffer.add_highlight(buf, ns, line_start, line_end, data, options)
|
||||
clear_namespace(buf, ns, line_start, line_end)
|
||||
function buffer.add_highlight(bufnr, ns_id, line_start, line_end, data, options)
|
||||
clear_namespace(bufnr, ns_id, line_start, line_end)
|
||||
|
||||
local mode = options.mode == "background" and "background" or "foreground"
|
||||
if vim.tbl_contains({ "foreground", "background" }, options.mode) then
|
||||
for linenr, hls in pairs(data) do
|
||||
for _, hl in ipairs(hls) do
|
||||
local hlname = create_highlight(hl.rgb_hex, mode)
|
||||
api.nvim_buf_add_highlight(buf, ns, hlname, linenr, hl.range[1], hl.range[2])
|
||||
api.nvim_buf_add_highlight(bufnr, ns_id, hlname, linenr, hl.range[1], hl.range[2])
|
||||
end
|
||||
end
|
||||
elseif options.mode == "virtualtext" then
|
||||
|
|
@ -125,7 +126,7 @@ function buffer.add_highlight(buf, ns, line_start, line_end, data, options)
|
|||
|
||||
opts.end_col = start_col
|
||||
|
||||
buf_set_virtual_text(buf, ns, linenr, start_col, opts)
|
||||
buf_set_virtual_text(bufnr, ns_id, linenr, start_col, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -133,35 +134,35 @@ end
|
|||
|
||||
--- Highlight the buffer region.
|
||||
-- Highlight starting from `line_start` (0-indexed) for each line described by `lines` in the
|
||||
-- buffer `buf` and attach it to the namespace `ns`.
|
||||
---@param buf number: buffer id
|
||||
---@param ns number: The namespace id. Default is DEFAULT_NAMESPACE. Create it with `vim.api.nvim_create_namespace`
|
||||
-- buffer id `bufnr` and attach it to the namespace id `ns_id`.
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
---@param ns_id number: namespace id. default is "colorizer", created with vim.api.nvim_create_namespace
|
||||
---@param line_start number: line_start should be 0-indexed
|
||||
---@param line_end number: Last line to highlight
|
||||
---@param options table: Configuration options as described in `setup`
|
||||
---@param options_local table: Buffer local variables
|
||||
---@return nil|boolean|number,table
|
||||
function buffer.highlight(buf, ns, line_start, line_end, options, options_local)
|
||||
local returns = { detach = { ns = {}, functions = {} } }
|
||||
if buf == 0 or buf == nil then
|
||||
buf = api.nvim_get_current_buf()
|
||||
function buffer.highlight(bufnr, ns_id, line_start, line_end, options, options_local)
|
||||
local returns = { detach = { ns_id = {}, functions = {} } }
|
||||
if bufnr == 0 or bufnr == nil then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
local lines = buf_get_lines(buf, line_start, line_end, false)
|
||||
local lines = buf_get_lines(bufnr, line_start, line_end, false)
|
||||
|
||||
ns = ns or buffer.default_namespace
|
||||
ns_id = ns_id or buffer.default_namespace
|
||||
|
||||
-- only update sass varibles when text is changed
|
||||
if options_local.__event ~= "WinScrolled" and options.sass and options.sass.enable then
|
||||
table.insert(returns.detach.functions, sass_cleanup)
|
||||
sass_update_variables(buf, 0, -1, nil, make_matcher(options.sass.parsers), options, options_local)
|
||||
sass_update_variables(bufnr, 0, -1, nil, make_matcher(options.sass.parsers), options, options_local)
|
||||
end
|
||||
|
||||
local data = buffer.parse_lines(buf, lines, line_start, options) or {}
|
||||
buffer.add_highlight(buf, ns, line_start, line_end, data, options)
|
||||
local data = buffer.parse_lines(bufnr, lines, line_start, options) or {}
|
||||
buffer.add_highlight(bufnr, ns_id, line_start, line_end, data, options)
|
||||
|
||||
if options.tailwind == "lsp" or options.tailwind == "both" then
|
||||
tailwind_setup_lsp(buf, options, options_local, buffer.add_highlight)
|
||||
tailwind_setup_lsp(bufnr, options, options_local, buffer.add_highlight)
|
||||
table.insert(returns.detach.functions, tailwind_cleanup)
|
||||
end
|
||||
|
||||
|
|
@ -170,12 +171,12 @@ end
|
|||
|
||||
--- Parse the given lines for colors and return a table containing
|
||||
-- rgb_hex and range per line
|
||||
---@param buf number
|
||||
---@param lines table
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
---@param lines table: table of lines to parse
|
||||
---@param line_start number: This is the buffer line number, from where to start highlighting
|
||||
---@param options table: Passed in `colorizer.setup`, Only uses `user_default_options`
|
||||
---@return table|nil
|
||||
function buffer.parse_lines(buf, lines, line_start, options)
|
||||
function buffer.parse_lines(bufnr, lines, line_start, options)
|
||||
local loop_parse_fn = make_matcher(options)
|
||||
if not loop_parse_fn then
|
||||
return
|
||||
|
|
@ -189,7 +190,7 @@ function buffer.parse_lines(buf, lines, line_start, options)
|
|||
-- Upvalues are options and current_linenum
|
||||
local i = 1
|
||||
while i < #line do
|
||||
local length, rgb_hex = loop_parse_fn(line, i, buf)
|
||||
local length, rgb_hex = loop_parse_fn(line, i, bufnr)
|
||||
if length and rgb_hex then
|
||||
table.insert(data[current_linenum], { rgb_hex = rgb_hex, range = { i - 1, i + length - 1 } })
|
||||
i = i + length
|
||||
|
|
@ -205,13 +206,10 @@ end
|
|||
-- gets used in rehighlight function only
|
||||
local BUFFER_LINES = {}
|
||||
-- get the amount lines to highlight
|
||||
local function getrow(buf)
|
||||
if not BUFFER_LINES[buf] then
|
||||
BUFFER_LINES[buf] = {}
|
||||
end
|
||||
local function getrow(bufnr)
|
||||
BUFFER_LINES[bufnr] = BUFFER_LINES[bufnr] or {}
|
||||
|
||||
local a = api.nvim_buf_call(buf, function()
|
||||
---@diagnostic disable-next-line: redundant-return-value
|
||||
local a = api.nvim_buf_call(bufnr, function()
|
||||
return {
|
||||
vim.fn.line "w0",
|
||||
vim.fn.line "w$",
|
||||
|
|
@ -219,7 +217,7 @@ local function getrow(buf)
|
|||
end)
|
||||
local min, max
|
||||
local new_min, new_max = a[1] - 1, a[2]
|
||||
local old_min, old_max = BUFFER_LINES[buf]["min"], BUFFER_LINES[buf]["max"]
|
||||
local old_min, old_max = BUFFER_LINES[bufnr]["min"], BUFFER_LINES[bufnr]["max"]
|
||||
|
||||
if old_min and old_max then
|
||||
-- Triggered for TextChanged autocmds
|
||||
|
|
@ -244,34 +242,32 @@ local function getrow(buf)
|
|||
min = min or new_min
|
||||
max = max or new_max
|
||||
-- store current window position to be used later to incremently highlight
|
||||
BUFFER_LINES[buf]["max"] = new_max
|
||||
BUFFER_LINES[buf]["min"] = new_min
|
||||
BUFFER_LINES[bufnr]["max"] = new_max
|
||||
BUFFER_LINES[bufnr]["min"] = new_min
|
||||
return min, max
|
||||
end
|
||||
|
||||
--- Rehighlight the buffer if colorizer is active
|
||||
---@param buf number: Buffer number
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
---@param options table: Buffer options
|
||||
---@param options_local table|nil: Buffer local variables
|
||||
---@param use_local_lines boolean|nil Whether to use lines num range from options_local
|
||||
---@return nil|boolean|number,table
|
||||
function buffer.rehighlight(buf, options, options_local, use_local_lines)
|
||||
if buf == 0 or buf == nil then
|
||||
buf = api.nvim_get_current_buf()
|
||||
end
|
||||
function buffer.rehighlight(bufnr, options, options_local, use_local_lines)
|
||||
bufnr = (bufnr == 0 or not bufnr) and current_buf() or bufnr
|
||||
|
||||
local ns = buffer.default_namespace
|
||||
local ns_id = buffer.default_namespace
|
||||
|
||||
local min, max
|
||||
if use_local_lines and options_local then
|
||||
min, max = options_local.__startline or 0, options_local.__endline or -1
|
||||
else
|
||||
min, max = getrow(buf)
|
||||
min, max = getrow(bufnr)
|
||||
end
|
||||
|
||||
local bool, returns = buffer.highlight(buf, ns, min, max, options, options_local or {})
|
||||
local bool, returns = buffer.highlight(bufnr, ns_id, min, max, options, options_local or {})
|
||||
table.insert(returns.detach.functions, function()
|
||||
BUFFER_LINES[buf] = nil
|
||||
BUFFER_LINES[bufnr] = nil
|
||||
end)
|
||||
|
||||
return bool, returns
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ function matcher.compile(matchers, matchers_trie)
|
|||
end
|
||||
|
||||
-- Prefix 0x, rgba, rgb, hsla, hsl
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
local prefix = trie:longest_prefix(line, i)
|
||||
if prefix then
|
||||
local fn = "_" .. prefix
|
||||
|
|
@ -85,18 +86,20 @@ function matcher.make(options)
|
|||
local enable_rgb = options.rgb_fn
|
||||
local enable_hsl = options.hsl_fn
|
||||
|
||||
-- Rather than use bit.lshift or calculate 2^x, use precalculated values to
|
||||
-- create unique bitmask
|
||||
local matcher_key = 0
|
||||
+ (enable_names and 1 or 0)
|
||||
+ (enable_RGB and 1 or 1)
|
||||
+ (enable_RRGGBB and 1 or 2)
|
||||
+ (enable_RRGGBBAA and 1 or 3)
|
||||
+ (enable_AARRGGBB and 1 or 4)
|
||||
+ (enable_rgb and 1 or 5)
|
||||
+ (enable_hsl and 1 or 6)
|
||||
+ ((enable_tailwind == true or enable_tailwind == "normal") and 1 or 7)
|
||||
+ (enable_tailwind == "lsp" and 1 or 8)
|
||||
+ (enable_tailwind == "both" and 1 or 9)
|
||||
+ (enable_sass and 1 or 10)
|
||||
+ (enable_RGB and 2 or 0)
|
||||
+ (enable_RRGGBB and 4 or 0)
|
||||
+ (enable_RRGGBBAA and 8 or 0)
|
||||
+ (enable_AARRGGBB and 16 or 0)
|
||||
+ (enable_rgb and 32 or 0)
|
||||
+ (enable_hsl and 64 or 0)
|
||||
+ ((enable_tailwind == true or enable_tailwind == "normal") and 128 or 0)
|
||||
+ (enable_tailwind == "lsp" and 256 or 0)
|
||||
+ (enable_tailwind == "both" and 512 or 0)
|
||||
+ (enable_sass and 1024 or 0)
|
||||
|
||||
if matcher_key == 0 then
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -34,10 +34,12 @@ function parser.name_parser(line, i, opts)
|
|||
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
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
COLOR_TRIE:insert(k)
|
||||
if COLOR_NAME_SETTINGS.lowercase then
|
||||
local lowercase = k:lower()
|
||||
COLOR_MAP[lowercase] = rgb_hex
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
COLOR_TRIE:insert(lowercase)
|
||||
end
|
||||
end
|
||||
|
|
@ -52,6 +54,7 @@ function parser.name_parser(line, i, opts)
|
|||
COLOR_NAME_MINLEN = COLOR_NAME_MINLEN and min(#name, COLOR_NAME_MINLEN) or #name
|
||||
COLOR_NAME_MAXLEN = COLOR_NAME_MAXLEN and max(#name, COLOR_NAME_MAXLEN) or #name
|
||||
COLOR_MAP[name] = v
|
||||
---@diagnostic disable-next-line: undefined-field
|
||||
COLOR_TRIE:insert(name)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,37 +15,37 @@ local COLON_HASH = (";"):byte()
|
|||
|
||||
local SASS = {}
|
||||
|
||||
local function remove_unused_imports(buf, import_name)
|
||||
if type(SASS[buf].IMPORTS[import_name]) == "table" then
|
||||
for file, _ in pairs(SASS[buf].IMPORTS[import_name]) do
|
||||
remove_unused_imports(buf, file)
|
||||
local function remove_unused_imports(bufnr, import_name)
|
||||
if type(SASS[bufnr].IMPORTS[import_name]) == "table" then
|
||||
for file, _ in pairs(SASS[bufnr].IMPORTS[import_name]) do
|
||||
remove_unused_imports(bufnr, file)
|
||||
end
|
||||
end
|
||||
SASS[buf].DEFINITIONS[import_name] = nil
|
||||
SASS[buf].DEFINITIONS_LINEWISE[import_name] = nil
|
||||
SASS[buf].IMPORTS[import_name] = nil
|
||||
SASS[bufnr].DEFINITIONS[import_name] = nil
|
||||
SASS[bufnr].DEFINITIONS_LINEWISE[import_name] = nil
|
||||
SASS[bufnr].IMPORTS[import_name] = nil
|
||||
-- stop the watch handler
|
||||
pcall(uv.fs_event_stop, SASS[buf].WATCH_IMPORTS[import_name])
|
||||
SASS[buf].WATCH_IMPORTS[import_name] = nil
|
||||
pcall(uv.fs_event_stop, SASS[bufnr].WATCH_IMPORTS[import_name])
|
||||
SASS[bufnr].WATCH_IMPORTS[import_name] = nil
|
||||
end
|
||||
|
||||
--- Cleanup sass variables and watch handlers
|
||||
---@param buf number
|
||||
function sass.cleanup(buf)
|
||||
remove_unused_imports(buf, api.nvim_buf_get_name(buf))
|
||||
SASS[buf] = nil
|
||||
---@param bufnr number
|
||||
function sass.cleanup(bufnr)
|
||||
remove_unused_imports(bufnr, api.nvim_buf_get_name(bufnr))
|
||||
SASS[bufnr] = nil
|
||||
end
|
||||
|
||||
--- Parse the given line for sass color names
|
||||
-- check for value in SASS[buf].DEFINITIONS_ALL
|
||||
---@param line string: Line to parse
|
||||
---@param i number: Index of line from where to start parsing
|
||||
---@param buf number
|
||||
---@param bufnr number
|
||||
---@return number|nil, string|nil
|
||||
function sass.name_parser(line, i, buf)
|
||||
function sass.name_parser(line, i, bufnr)
|
||||
local variable_name = line:match("^%$([%w_-]+)", i)
|
||||
if variable_name then
|
||||
local rgb_hex = SASS[buf].DEFINITIONS_ALL[variable_name]
|
||||
local rgb_hex = SASS[bufnr].DEFINITIONS_ALL[variable_name]
|
||||
if rgb_hex then
|
||||
return #variable_name + 1, rgb_hex
|
||||
end
|
||||
|
|
@ -53,28 +53,28 @@ function sass.name_parser(line, i, buf)
|
|||
end
|
||||
|
||||
-- Helper function for sass_update_variables
|
||||
local function sass_parse_lines(buf, line_start, content, name)
|
||||
SASS[buf].DEFINITIONS_ALL = SASS[buf].DEFINITIONS_ALL or {}
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = SASS[buf].DEFINITIONS_RECURSIVE_CURRENT or {}
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE or {}
|
||||
local function sass_parse_lines(bufnr, line_start, content, name)
|
||||
SASS[bufnr].DEFINITIONS_ALL = SASS[bufnr].DEFINITIONS_ALL or {}
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT = SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT or {}
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE or {}
|
||||
|
||||
SASS[buf].DEFINITIONS_LINEWISE[name] = SASS[buf].DEFINITIONS_LINEWISE[name] or {}
|
||||
SASS[buf].DEFINITIONS[name] = SASS[buf].DEFINITIONS[name] or {}
|
||||
SASS[buf].IMPORTS[name] = SASS[buf].IMPORTS[name] or {}
|
||||
SASS[buf].WATCH_IMPORTS[name] = SASS[buf].WATCH_IMPORTS[name] or {}
|
||||
SASS[buf].CURRENT_IMPORTS[name] = {}
|
||||
SASS[bufnr].DEFINITIONS_LINEWISE[name] = SASS[bufnr].DEFINITIONS_LINEWISE[name] or {}
|
||||
SASS[bufnr].DEFINITIONS[name] = SASS[bufnr].DEFINITIONS[name] or {}
|
||||
SASS[bufnr].IMPORTS[name] = SASS[bufnr].IMPORTS[name] or {}
|
||||
SASS[bufnr].WATCH_IMPORTS[name] = SASS[bufnr].WATCH_IMPORTS[name] or {}
|
||||
SASS[bufnr].CURRENT_IMPORTS[name] = {}
|
||||
|
||||
local import_find_colon = false
|
||||
for i, line in ipairs(content) do
|
||||
local linenum = i - 1 + line_start
|
||||
-- Invalidate any existing definitions for the lines we are processing.
|
||||
if not vim.tbl_isempty(SASS[buf].DEFINITIONS_LINEWISE[name][linenum] or {}) then
|
||||
for v, _ in pairs(SASS[buf].DEFINITIONS_LINEWISE[name][linenum]) do
|
||||
SASS[buf].DEFINITIONS[name][v] = nil
|
||||
if not vim.tbl_isempty(SASS[bufnr].DEFINITIONS_LINEWISE[name][linenum] or {}) then
|
||||
for v, _ in pairs(SASS[bufnr].DEFINITIONS_LINEWISE[name][linenum]) do
|
||||
SASS[bufnr].DEFINITIONS[name][v] = nil
|
||||
end
|
||||
SASS[buf].DEFINITIONS_LINEWISE[name][linenum] = {}
|
||||
SASS[bufnr].DEFINITIONS_LINEWISE[name][linenum] = {}
|
||||
else
|
||||
SASS[buf].DEFINITIONS_LINEWISE[name][linenum] = {}
|
||||
SASS[bufnr].DEFINITIONS_LINEWISE[name][linenum] = {}
|
||||
end
|
||||
|
||||
local index = 1
|
||||
|
|
@ -92,21 +92,21 @@ local function sass_parse_lines(buf, line_start, content, name)
|
|||
local target_variable_name, len = variable_value:match "^%$([%w_-]+)()"
|
||||
if target_variable_name then
|
||||
-- Update the value.
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = target_variable_name
|
||||
SASS[buf].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = target_variable_name
|
||||
SASS[bufnr].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true
|
||||
index = index + len
|
||||
end
|
||||
index = index + 1
|
||||
else
|
||||
-- Check for a recursive variable definition.
|
||||
-- If it's not recursive, then just update the value.
|
||||
if SASS[buf].COLOR_PARSER then
|
||||
local length, rgb_hex = SASS[buf].COLOR_PARSER(variable_value, 1)
|
||||
if SASS[bufnr].COLOR_PARSER then
|
||||
local length, rgb_hex = SASS[bufnr].COLOR_PARSER(variable_value, 1)
|
||||
if length and rgb_hex then
|
||||
SASS[buf].DEFINITIONS[name][variable_name] = rgb_hex
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = rgb_hex
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE[variable_name] = rgb_hex
|
||||
SASS[buf].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true
|
||||
SASS[bufnr].DEFINITIONS[name][variable_name] = rgb_hex
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT[variable_name] = rgb_hex
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE[variable_name] = rgb_hex
|
||||
SASS[bufnr].DEFINITIONS_LINEWISE[name][linenum][variable_name] = true
|
||||
-- added 3 because the color parsers returns 3 less
|
||||
-- todo: need to fix
|
||||
index = index + length + 3
|
||||
|
|
@ -163,58 +163,59 @@ local function sass_parse_lines(buf, line_start, content, name)
|
|||
if last_modified then
|
||||
-- grab the full path
|
||||
v = uv.fs_realpath(v)
|
||||
SASS[buf].CURRENT_IMPORTS[name][v or ""] = true
|
||||
if v then
|
||||
SASS[bufnr].CURRENT_IMPORTS[name][v or ""] = true
|
||||
|
||||
if not SASS[buf].WATCH_IMPORTS[name][v] then
|
||||
SASS[buf].IMPORTS[name][v or ""] = last_modified
|
||||
local c, ind = {}, 0
|
||||
for l in io.lines(v) do
|
||||
ind = ind + 1
|
||||
c[ind] = l
|
||||
end
|
||||
sass_parse_lines(buf, 0, c, v)
|
||||
c = nil
|
||||
|
||||
local function watch_callback()
|
||||
local dimen = vim.api.nvim_buf_call(buf, function()
|
||||
---@diagnostic disable-next-line: redundant-return-value
|
||||
return { vim.fn.line "w0", vim.fn.line "w$", vim.fn.line "$", vim.api.nvim_win_get_height(0) }
|
||||
end)
|
||||
-- todo: Improve this to only refresh highlight for visible lines
|
||||
-- can't find out how to get visible rows from another window
|
||||
-- probably a neovim bug, it is returning 1 and 1 or 1 and 5
|
||||
if
|
||||
SASS[buf].LOCAL_OPTIONS
|
||||
and dimen[1] ~= dimen[2]
|
||||
and ((dimen[3] > dimen[4] and dimen[2] > dimen[4]) or (dimen[2] >= dimen[3]))
|
||||
then
|
||||
SASS[buf].LOCAL_OPTIONS.__startline = dimen[1]
|
||||
SASS[buf].LOCAL_OPTIONS.__endline = dimen[2]
|
||||
if not SASS[bufnr].WATCH_IMPORTS[name][v] then
|
||||
SASS[bufnr].IMPORTS[name][v or ""] = last_modified
|
||||
local c, ind = {}, 0
|
||||
for l in io.lines(v) do
|
||||
ind = ind + 1
|
||||
c[ind] = l
|
||||
end
|
||||
SASS[buf].LOCAL_OPTIONS.__event = ""
|
||||
sass_parse_lines(bufnr, 0, c, v)
|
||||
c = nil
|
||||
|
||||
local lastm = get_last_modified(v)
|
||||
if lastm then
|
||||
SASS[buf].IMPORTS[name] = SASS[buf].IMPORTS[name] or {}
|
||||
SASS[buf].IMPORTS[name][v] = lastm
|
||||
local cc, inde = {}, 0
|
||||
for l in io.lines(v) do
|
||||
inde = inde + 1
|
||||
cc[inde] = l
|
||||
local function watch_callback()
|
||||
local dimen = vim.api.nvim_buf_call(bufnr, function()
|
||||
return { vim.fn.line "w0", vim.fn.line "w$", vim.fn.line "$", vim.api.nvim_win_get_height(0) }
|
||||
end)
|
||||
-- todo: Improve this to only refresh highlight for visible lines
|
||||
-- can't find out how to get visible rows from another window
|
||||
-- probably a neovim bug, it is returning 1 and 1 or 1 and 5
|
||||
if
|
||||
SASS[bufnr].LOCAL_OPTIONS
|
||||
and dimen[1] ~= dimen[2]
|
||||
and ((dimen[3] > dimen[4] and dimen[2] > dimen[4]) or (dimen[2] >= dimen[3]))
|
||||
then
|
||||
SASS[bufnr].LOCAL_OPTIONS.__startline = dimen[1]
|
||||
SASS[bufnr].LOCAL_OPTIONS.__endline = dimen[2]
|
||||
end
|
||||
sass_parse_lines(buf, 0, cc, v)
|
||||
cc = nil
|
||||
end
|
||||
SASS[bufnr].LOCAL_OPTIONS.__event = ""
|
||||
|
||||
require("colorizer.buffer").rehighlight(buf, SASS[buf].OPTIONS, SASS[buf].LOCAL_OPTIONS, true)
|
||||
local lastm = get_last_modified(v)
|
||||
if lastm then
|
||||
SASS[bufnr].IMPORTS[name] = SASS[bufnr].IMPORTS[name] or {}
|
||||
SASS[bufnr].IMPORTS[name][v] = lastm
|
||||
local cc, inde = {}, 0
|
||||
for l in io.lines(v) do
|
||||
inde = inde + 1
|
||||
cc[inde] = l
|
||||
end
|
||||
sass_parse_lines(bufnr, 0, cc, v)
|
||||
cc = nil
|
||||
end
|
||||
|
||||
require("colorizer.buffer").rehighlight(bufnr, SASS[bufnr].OPTIONS, SASS[bufnr].LOCAL_OPTIONS, true)
|
||||
end
|
||||
SASS[bufnr].WATCH_IMPORTS[name][v] = watch_file(v, watch_callback)
|
||||
end
|
||||
SASS[buf].WATCH_IMPORTS[name][v] = watch_file(v, watch_callback)
|
||||
end
|
||||
else
|
||||
-- if file does not exists then remove related variables
|
||||
SASS[buf].IMPORTS[name][v] = nil
|
||||
pcall(uv.fs_event_stop, SASS[buf].WATCH_IMPORTS[name][v])
|
||||
SASS[buf].WATCH_IMPORTS[name][v] = nil
|
||||
SASS[bufnr].IMPORTS[name][v] = nil
|
||||
pcall(uv.fs_event_stop, SASS[bufnr].WATCH_IMPORTS[name][v])
|
||||
SASS[bufnr].WATCH_IMPORTS[name][v] = nil
|
||||
end
|
||||
end -- process imported files
|
||||
end
|
||||
|
|
@ -224,9 +225,9 @@ local function sass_parse_lines(buf, line_start, content, name)
|
|||
end -- for loop end
|
||||
|
||||
-- remove definitions of files which are not imported now
|
||||
for file, _ in pairs(SASS[buf].IMPORTS[name]) do
|
||||
if not SASS[buf].CURRENT_IMPORTS[name][file] then
|
||||
remove_unused_imports(buf, name)
|
||||
for file, _ in pairs(SASS[bufnr].IMPORTS[name]) do
|
||||
if not SASS[bufnr].CURRENT_IMPORTS[name][file] then
|
||||
remove_unused_imports(bufnr, name)
|
||||
end
|
||||
end
|
||||
end -- sass_parse_lines end
|
||||
|
|
@ -234,18 +235,18 @@ end -- sass_parse_lines end
|
|||
--- Parse the given lines for sass variabled and add to `SASS[buf].DEFINITIONS_ALL`.
|
||||
-- which is then used in |sass_name_parser|
|
||||
-- If lines are not given, then fetch the lines with line_start and line_end
|
||||
---@param buf number
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
---@param line_start number
|
||||
---@param line_end number
|
||||
---@param lines table|nil
|
||||
---@param color_parser function|boolean
|
||||
---@param options table: Buffer options
|
||||
---@param options_local table|nil: Buffer local variables
|
||||
function sass.update_variables(buf, line_start, line_end, lines, color_parser, options, options_local)
|
||||
lines = lines or vim.api.nvim_buf_get_lines(buf, line_start, line_end, false)
|
||||
function sass.update_variables(bufnr, line_start, line_end, lines, color_parser, options, options_local)
|
||||
lines = lines or vim.api.nvim_buf_get_lines(bufnr, line_start, line_end, false)
|
||||
|
||||
if not SASS[buf] then
|
||||
SASS[buf] = {
|
||||
if not SASS[bufnr] then
|
||||
SASS[bufnr] = {
|
||||
DEFINITIONS_ALL = {},
|
||||
DEFINITIONS = {},
|
||||
IMPORTS = {},
|
||||
|
|
@ -257,52 +258,52 @@ function sass.update_variables(buf, line_start, line_end, lines, color_parser, o
|
|||
}
|
||||
end
|
||||
|
||||
SASS[buf].COLOR_PARSER = color_parser
|
||||
SASS[buf].DEFINITIONS_ALL = {}
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = {}
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = {}
|
||||
SASS[bufnr].COLOR_PARSER = color_parser
|
||||
SASS[bufnr].DEFINITIONS_ALL = {}
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT = {}
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = {}
|
||||
|
||||
sass_parse_lines(buf, line_start, lines, api.nvim_buf_get_name(buf))
|
||||
sass_parse_lines(bufnr, line_start, lines, api.nvim_buf_get_name(bufnr))
|
||||
|
||||
-- add non-recursive def to DEFINITIONS_ALL
|
||||
for _, color_table in pairs(SASS[buf].DEFINITIONS) do
|
||||
for _, color_table in pairs(SASS[bufnr].DEFINITIONS) do
|
||||
for color_name, color in pairs(color_table) do
|
||||
SASS[buf].DEFINITIONS_ALL[color_name] = color
|
||||
SASS[bufnr].DEFINITIONS_ALL[color_name] = color
|
||||
end
|
||||
end
|
||||
|
||||
-- normally this is just a wasted step as all the values here are
|
||||
-- already present in SASS[buf].DEFINITIONS
|
||||
-- but when undoing a pasted text, it acts as a backup
|
||||
for name, color in pairs(SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE) do
|
||||
SASS[buf].DEFINITIONS_ALL[name] = color
|
||||
for name, color in pairs(SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE) do
|
||||
SASS[bufnr].DEFINITIONS_ALL[name] = color
|
||||
end
|
||||
|
||||
-- try to find the absolute color value for the given name
|
||||
-- use tail call recursion
|
||||
-- https://www.lua.org/pil/6.3.html
|
||||
local function find_absolute_value(name, color_name)
|
||||
return SASS[buf].DEFINITIONS_ALL[color_name]
|
||||
return SASS[bufnr].DEFINITIONS_ALL[color_name]
|
||||
or (
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[color_name]
|
||||
and find_absolute_value(name, SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[color_name])
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT[color_name]
|
||||
and find_absolute_value(name, SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT[color_name])
|
||||
)
|
||||
end
|
||||
|
||||
local function set_color_value(name, color_name)
|
||||
local value = find_absolute_value(name, color_name)
|
||||
if value then
|
||||
SASS[buf].DEFINITIONS_ALL[name] = value
|
||||
SASS[bufnr].DEFINITIONS_ALL[name] = value
|
||||
end
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT[name] = nil
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT[name] = nil
|
||||
end
|
||||
|
||||
for name, color_name in pairs(SASS[buf].DEFINITIONS_RECURSIVE_CURRENT) do
|
||||
for name, color_name in pairs(SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT) do
|
||||
set_color_value(name, color_name)
|
||||
end
|
||||
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT = nil
|
||||
SASS[buf].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = nil
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT = nil
|
||||
SASS[bufnr].DEFINITIONS_RECURSIVE_CURRENT_ABSOLUTE = nil
|
||||
end
|
||||
|
||||
return sass
|
||||
|
|
|
|||
|
|
@ -10,28 +10,26 @@ local DEFAULT_NAMESPACE_TAILWIND = api.nvim_create_namespace "colorizer_tailwind
|
|||
local TAILWIND = {}
|
||||
|
||||
--- Cleanup tailwind variables and autocmd
|
||||
---@param buf number
|
||||
function tailwind.cleanup(buf)
|
||||
if TAILWIND[buf] and TAILWIND[buf].AU_ID and TAILWIND[buf].AU_ID[1] then
|
||||
pcall(api.nvim_del_autocmd, TAILWIND[buf].AU_ID[1])
|
||||
pcall(api.nvim_del_autocmd, TAILWIND[buf].AU_ID[2])
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
function tailwind.cleanup(bufnr)
|
||||
if TAILWIND[bufnr] and TAILWIND[bufnr].AU_ID and TAILWIND[bufnr].AU_ID[1] then
|
||||
pcall(api.nvim_del_autocmd, TAILWIND[bufnr].AU_ID[1])
|
||||
pcall(api.nvim_del_autocmd, TAILWIND[bufnr].AU_ID[2])
|
||||
end
|
||||
api.nvim_buf_clear_namespace(buf, DEFAULT_NAMESPACE_TAILWIND, 0, -1)
|
||||
TAILWIND[buf] = nil
|
||||
api.nvim_buf_clear_namespace(bufnr, DEFAULT_NAMESPACE_TAILWIND, 0, -1)
|
||||
TAILWIND[bufnr] = nil
|
||||
end
|
||||
|
||||
local function highlight_tailwind(buf, ns, options, add_highlight)
|
||||
local function highlight_tailwind(bufnr, ns, options, add_highlight)
|
||||
-- it can take some time to actually fetch the results
|
||||
-- on top of that, tailwindcss is quite slow in neovim
|
||||
vim.defer_fn(function()
|
||||
if not TAILWIND[buf] or not TAILWIND[buf].CLIENT or not TAILWIND[buf].CLIENT.request then
|
||||
if not TAILWIND[bufnr] or not TAILWIND[bufnr].CLIENT or not TAILWIND[bufnr].CLIENT.request then
|
||||
return
|
||||
end
|
||||
|
||||
local opts = { textDocument = vim.lsp.util.make_text_document_params() }
|
||||
--@local
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
TAILWIND[buf].CLIENT.request("textDocument/documentColor", opts, function(err, results, _, _)
|
||||
TAILWIND[bufnr].CLIENT.request("textDocument/documentColor", opts, function(err, results, _, _)
|
||||
if err == nil and results ~= nil then
|
||||
local data, line_start, line_end = {}, nil, nil
|
||||
for _, color in pairs(results) do
|
||||
|
|
@ -61,7 +59,7 @@ local function highlight_tailwind(buf, ns, options, add_highlight)
|
|||
data[cur_line] = data[cur_line] or {}
|
||||
table.insert(data[cur_line], { rgb_hex = rgb_hex, range = { first_col, end_col } })
|
||||
end
|
||||
add_highlight(buf, ns, line_start or 0, line_end and (line_end + 2) or -1, data, options)
|
||||
add_highlight(bufnr, ns, line_start or 0, line_end and (line_end + 2) or -1, data, options)
|
||||
end
|
||||
end)
|
||||
end, 10)
|
||||
|
|
@ -69,53 +67,53 @@ end
|
|||
|
||||
--- highlight buffer using values returned by tailwindcss
|
||||
-- To see these table information, see |colorizer.buffer|
|
||||
---@param buf number
|
||||
---@param bufnr number: buffer number (0 for current)
|
||||
---@param options table
|
||||
---@param options_local table
|
||||
---@param add_highlight function
|
||||
function tailwind.setup_lsp_colors(buf, options, options_local, add_highlight)
|
||||
TAILWIND[buf] = TAILWIND[buf] or {}
|
||||
TAILWIND[buf].AU_ID = TAILWIND[buf].AU_ID or {}
|
||||
function tailwind.setup_lsp_colors(bufnr, options, options_local, add_highlight)
|
||||
TAILWIND[bufnr] = TAILWIND[bufnr] or {}
|
||||
TAILWIND[bufnr].AU_ID = TAILWIND[bufnr].AU_ID or {}
|
||||
|
||||
if not TAILWIND[buf].CLIENT or TAILWIND[buf].CLIENT.is_stopped() then
|
||||
if not TAILWIND[bufnr].CLIENT or TAILWIND[bufnr].CLIENT.is_stopped() then
|
||||
if vim.version().minor >= 8 then
|
||||
-- create the autocmds so tailwind colours only activate when tailwindcss lsp is active
|
||||
if not TAILWIND[buf].AU_CREATED then
|
||||
api.nvim_buf_clear_namespace(buf, DEFAULT_NAMESPACE_TAILWIND, 0, -1)
|
||||
TAILWIND[buf].AU_ID[1] = api.nvim_create_autocmd("LspAttach", {
|
||||
if not TAILWIND[bufnr].AU_CREATED then
|
||||
api.nvim_buf_clear_namespace(bufnr, DEFAULT_NAMESPACE_TAILWIND, 0, -1)
|
||||
TAILWIND[bufnr].AU_ID[1] = api.nvim_create_autocmd("LspAttach", {
|
||||
group = options_local.__augroup_id,
|
||||
buffer = buf,
|
||||
buffer = bufnr,
|
||||
callback = function(args)
|
||||
local ok, client = pcall(vim.lsp.get_client_by_id, args.data.client_id)
|
||||
if ok then
|
||||
if client.name == "tailwindcss" and client.supports_method "textDocument/documentColor" then
|
||||
-- wait 100 ms for the first request
|
||||
TAILWIND[buf].CLIENT = client
|
||||
TAILWIND[bufnr].CLIENT = client
|
||||
vim.defer_fn(function()
|
||||
highlight_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight)
|
||||
highlight_tailwind(bufnr, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight)
|
||||
end, 100)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
-- make sure the autocmds are deleted after lsp server is closed
|
||||
TAILWIND[buf].AU_ID[2] = api.nvim_create_autocmd("LspDetach", {
|
||||
TAILWIND[bufnr].AU_ID[2] = api.nvim_create_autocmd("LspDetach", {
|
||||
group = options_local.__augroup_id,
|
||||
buffer = buf,
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
tailwind.cleanup(buf)
|
||||
tailwind.cleanup(bufnr)
|
||||
end,
|
||||
})
|
||||
TAILWIND[buf].AU_CREATED = true
|
||||
TAILWIND[bufnr].AU_CREATED = true
|
||||
end
|
||||
end
|
||||
-- this will be triggered when no lsp is attached
|
||||
api.nvim_buf_clear_namespace(buf, DEFAULT_NAMESPACE_TAILWIND, 0, -1)
|
||||
api.nvim_buf_clear_namespace(bufnr, DEFAULT_NAMESPACE_TAILWIND, 0, -1)
|
||||
|
||||
TAILWIND[buf].CLIENT = nil
|
||||
TAILWIND[bufnr].CLIENT = nil
|
||||
|
||||
local ok, tailwind_client = pcall(function()
|
||||
return vim.lsp.get_clients { bufnr = buf, name = "tailwindcss" }
|
||||
return vim.lsp.get_clients { bufnr = bufnr, name = "tailwindcss" }
|
||||
end)
|
||||
if not ok then
|
||||
return
|
||||
|
|
@ -142,19 +140,19 @@ function tailwind.setup_lsp_colors(buf, options, options_local, add_highlight)
|
|||
return true
|
||||
end
|
||||
|
||||
TAILWIND[buf].CLIENT = tailwind_client
|
||||
TAILWIND[bufnr].CLIENT = tailwind_client
|
||||
|
||||
-- wait 500 ms for the first request
|
||||
vim.defer_fn(function()
|
||||
highlight_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight)
|
||||
highlight_tailwind(bufnr, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight)
|
||||
end, 1000)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- only try to do tailwindcss highlight if lsp is attached
|
||||
if TAILWIND[buf].CLIENT then
|
||||
highlight_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight)
|
||||
if TAILWIND[bufnr].CLIENT then
|
||||
highlight_tailwind(bufnr, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -269,6 +269,6 @@ return {
|
|||
["rose-700"] = "be123c",
|
||||
["rose-800"] = "9f1239",
|
||||
["rose-900"] = "881337",
|
||||
["rose-950"] = "4c0519"
|
||||
["rose-950"] = "4c0519",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ local Trie_size = ffi.sizeof(Trie_t)
|
|||
|
||||
local function trie_create()
|
||||
local ptr = ffi.C.malloc(Trie_size)
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
ffi.fill(ptr, Trie_size)
|
||||
return ffi.cast(Trie_ptr_t, ptr)
|
||||
end
|
||||
|
|
@ -164,7 +165,7 @@ end
|
|||
|
||||
local function trie_as_table(trie)
|
||||
if trie == nil then
|
||||
return nil
|
||||
return
|
||||
end
|
||||
local children = {}
|
||||
for i = 0, 61 do
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ end
|
|||
---@param path string: File path
|
||||
---@param callback function: Callback to execute
|
||||
---@param ... table: params for callback
|
||||
---@return function|nil
|
||||
---@return uv_fs_event_t|nil
|
||||
function utils.watch_file(path, callback, ...)
|
||||
if not path or type(callback) ~= "function" then
|
||||
return
|
||||
|
|
@ -141,6 +141,9 @@ function utils.watch_file(path, callback, ...)
|
|||
local args = { ... }
|
||||
|
||||
local handle = uv.new_fs_event()
|
||||
if not handle then
|
||||
return
|
||||
end
|
||||
local function on_change(err, filename, _)
|
||||
-- Do work...
|
||||
callback(filename, unpack(args))
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ end
|
|||
local command = vim.api.nvim_create_user_command
|
||||
|
||||
command("ColorizerAttachToBuffer", function()
|
||||
require("colorizer").attach_to_buffer(0)
|
||||
require("colorizer").attach_to_buffer()
|
||||
end, {})
|
||||
|
||||
-- Stop highlighting the current buffer (detach).
|
||||
command("ColorizerDetachFromBuffer", function()
|
||||
require("colorizer").detach_from_buffer(0)
|
||||
require("colorizer").detach_from_buffer()
|
||||
end, {})
|
||||
|
||||
command("ColorizerReloadAllBuffers", function()
|
||||
|
|
@ -19,10 +19,10 @@ end, {})
|
|||
|
||||
command("ColorizerToggle", function()
|
||||
local c = require "colorizer"
|
||||
if c.is_buffer_attached(0) then
|
||||
c.detach_from_buffer(0)
|
||||
if c.is_buffer_attached() then
|
||||
c.detach_from_buffer()
|
||||
else
|
||||
c.attach_to_buffer(0)
|
||||
c.attach_to_buffer()
|
||||
end
|
||||
end, {})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
-- vim:ft=lua
|
||||
require("colorizer").detach_from_buffer(0)
|
||||
require("colorizer").detach_from_buffer()
|
||||
require("colorizer").attach_to_buffer(0, { AARRGGBB = true, css = true, mode = "foreground" })
|
||||
--[[ SUCCESS
|
||||
0xFf32A14B 0xFf32A14B
|
||||
|
|
|
|||
275
test/tailwind.html
Normal file
275
test/tailwind.html
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
<div
|
||||
class="
|
||||
accent-blue-100
|
||||
bg-gray-200
|
||||
border-black
|
||||
border-x-zinc-300
|
||||
border-y-yellow-400
|
||||
border-t-teal-500
|
||||
border-r-neutral-600
|
||||
border-b-blue-700
|
||||
border-l-lime-800
|
||||
caret-indigo-900
|
||||
decoration-sky-950
|
||||
divide-white
|
||||
fill-violet-950
|
||||
from-indigo-900
|
||||
shadow-blue-800
|
||||
stroke-sky-700
|
||||
text-cyan-500
|
||||
to-red-400
|
||||
via-green-300
|
||||
ring-emerald-200
|
||||
ring-offset-violet-100
|
||||
"
|
||||
>Prefixes</div>
|
||||
<div
|
||||
class="
|
||||
text-black
|
||||
text-white
|
||||
text-slate-50
|
||||
text-slate-100
|
||||
text-slate-200
|
||||
text-slate-300
|
||||
text-slate-400
|
||||
text-slate-500
|
||||
text-slate-600
|
||||
text-slate-700
|
||||
text-slate-800
|
||||
text-slate-900
|
||||
text-slate-950
|
||||
text-gray-50
|
||||
text-gray-100
|
||||
text-gray-200
|
||||
text-gray-300
|
||||
text-gray-400
|
||||
text-gray-500
|
||||
text-gray-600
|
||||
text-gray-700
|
||||
text-gray-800
|
||||
text-gray-900
|
||||
text-gray-950
|
||||
text-zinc-50
|
||||
text-zinc-100
|
||||
text-zinc-200
|
||||
text-zinc-300
|
||||
text-zinc-400
|
||||
text-zinc-500
|
||||
text-zinc-600
|
||||
text-zinc-700
|
||||
text-zinc-800
|
||||
text-zinc-900
|
||||
text-zinc-950
|
||||
text-neutral-50
|
||||
text-neutral-100
|
||||
text-neutral-200
|
||||
text-neutral-300
|
||||
text-neutral-400
|
||||
text-neutral-500
|
||||
text-neutral-600
|
||||
text-neutral-700
|
||||
text-neutral-800
|
||||
text-neutral-900
|
||||
text-neutral-950
|
||||
text-stone-50
|
||||
text-stone-100
|
||||
text-stone-200
|
||||
text-stone-300
|
||||
text-stone-400
|
||||
text-stone-500
|
||||
text-stone-600
|
||||
text-stone-700
|
||||
text-stone-800
|
||||
text-stone-900
|
||||
text-stone-950
|
||||
text-red-50
|
||||
text-red-100
|
||||
text-red-200
|
||||
text-red-300
|
||||
text-red-400
|
||||
text-red-500
|
||||
text-red-600
|
||||
text-red-700
|
||||
text-red-800
|
||||
text-red-900
|
||||
text-red-950
|
||||
text-orange-50
|
||||
text-orange-100
|
||||
text-orange-200
|
||||
text-orange-300
|
||||
text-orange-400
|
||||
text-orange-500
|
||||
text-orange-600
|
||||
text-orange-700
|
||||
text-orange-800
|
||||
text-orange-900
|
||||
text-orange-950
|
||||
text-amber-50
|
||||
text-amber-100
|
||||
text-amber-200
|
||||
text-amber-300
|
||||
text-amber-400
|
||||
text-amber-500
|
||||
text-amber-600
|
||||
text-amber-700
|
||||
text-amber-800
|
||||
text-amber-900
|
||||
text-amber-950
|
||||
text-yellow-50
|
||||
text-yellow-100
|
||||
text-yellow-200
|
||||
text-yellow-300
|
||||
text-yellow-400
|
||||
text-yellow-500
|
||||
text-yellow-600
|
||||
text-yellow-700
|
||||
text-yellow-800
|
||||
text-yellow-900
|
||||
text-yellow-950
|
||||
text-lime-50
|
||||
text-lime-100
|
||||
text-lime-200
|
||||
text-lime-300
|
||||
text-lime-400
|
||||
text-lime-500
|
||||
text-lime-600
|
||||
text-lime-700
|
||||
text-lime-800
|
||||
text-lime-900
|
||||
text-lime-950
|
||||
text-green-50
|
||||
text-green-100
|
||||
text-green-200
|
||||
text-green-300
|
||||
text-green-400
|
||||
text-green-500
|
||||
text-green-600
|
||||
text-green-700
|
||||
text-green-800
|
||||
text-green-900
|
||||
text-green-950
|
||||
text-emerald-50
|
||||
text-emerald-100
|
||||
text-emerald-200
|
||||
text-emerald-300
|
||||
text-emerald-400
|
||||
text-emerald-500
|
||||
text-emerald-600
|
||||
text-emerald-700
|
||||
text-emerald-800
|
||||
text-emerald-900
|
||||
text-emerald-950
|
||||
text-teal-50
|
||||
text-teal-100
|
||||
text-teal-200
|
||||
text-teal-300
|
||||
text-teal-400
|
||||
text-teal-500
|
||||
text-teal-600
|
||||
text-teal-700
|
||||
text-teal-800
|
||||
text-teal-900
|
||||
text-teal-950
|
||||
text-cyan-50
|
||||
text-cyan-100
|
||||
text-cyan-200
|
||||
text-cyan-300
|
||||
text-cyan-400
|
||||
text-cyan-500
|
||||
text-cyan-600
|
||||
text-cyan-700
|
||||
text-cyan-800
|
||||
text-cyan-900
|
||||
text-cyan-950
|
||||
text-sky-50
|
||||
text-sky-100
|
||||
text-sky-200
|
||||
text-sky-300
|
||||
text-sky-400
|
||||
text-sky-500
|
||||
text-sky-600
|
||||
text-sky-700
|
||||
text-sky-800
|
||||
text-sky-900
|
||||
text-sky-950
|
||||
text-blue-50
|
||||
text-blue-100
|
||||
text-blue-200
|
||||
text-blue-300
|
||||
text-blue-400
|
||||
text-blue-500
|
||||
text-blue-600
|
||||
text-blue-700
|
||||
text-blue-800
|
||||
text-blue-900
|
||||
text-blue-950
|
||||
text-indigo-50
|
||||
text-indigo-100
|
||||
text-indigo-200
|
||||
text-indigo-300
|
||||
text-indigo-400
|
||||
text-indigo-500
|
||||
text-indigo-600
|
||||
text-indigo-700
|
||||
text-indigo-800
|
||||
text-indigo-900
|
||||
text-indigo-950
|
||||
text-violet-50
|
||||
text-violet-100
|
||||
text-violet-200
|
||||
text-violet-300
|
||||
text-violet-400
|
||||
text-violet-500
|
||||
text-violet-600
|
||||
text-violet-700
|
||||
text-violet-800
|
||||
text-violet-900
|
||||
text-violet-950
|
||||
text-purple-50
|
||||
text-purple-100
|
||||
text-purple-200
|
||||
text-purple-300
|
||||
text-purple-400
|
||||
text-purple-500
|
||||
text-purple-600
|
||||
text-purple-700
|
||||
text-purple-800
|
||||
text-purple-900
|
||||
text-purple-950
|
||||
text-fuchsia-50
|
||||
text-fuchsia-100
|
||||
text-fuchsia-200
|
||||
text-fuchsia-300
|
||||
text-fuchsia-400
|
||||
text-fuchsia-500
|
||||
text-fuchsia-600
|
||||
text-fuchsia-700
|
||||
text-fuchsia-800
|
||||
text-fuchsia-900
|
||||
text-fuchsia-950
|
||||
text-pink-50
|
||||
text-pink-100
|
||||
text-pink-200
|
||||
text-pink-300
|
||||
text-pink-400
|
||||
text-pink-500
|
||||
text-pink-600
|
||||
text-pink-700
|
||||
text-pink-800
|
||||
text-pink-900
|
||||
text-pink-950
|
||||
text-rose-50
|
||||
text-rose-100
|
||||
text-rose-200
|
||||
text-rose-300
|
||||
text-rose-400
|
||||
text-rose-500
|
||||
text-rose-600
|
||||
text-rose-700
|
||||
text-rose-800
|
||||
text-rose-900
|
||||
text-rose-950
|
||||
"
|
||||
>
|
||||
Colors
|
||||
</div>
|
||||
Loading…
Reference in a new issue