diff --git a/lua/colorizer.lua b/lua/colorizer.lua index ac8799b..c6fa124 100644 --- a/lua/colorizer.lua +++ b/lua/colorizer.lua @@ -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 - 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) +---@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 - 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 diff --git a/lua/colorizer/buffer.lua b/lua/colorizer/buffer.lua index 9defecd..717e9fd 100644 --- a/lua/colorizer/buffer.lua +++ b/lua/colorizer/buffer.lua @@ -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 diff --git a/lua/colorizer/matcher.lua b/lua/colorizer/matcher.lua index 1f3eede..e7ed656 100644 --- a/lua/colorizer/matcher.lua +++ b/lua/colorizer/matcher.lua @@ -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 diff --git a/lua/colorizer/parser/names.lua b/lua/colorizer/parser/names.lua index 6fc7043..5261d70 100644 --- a/lua/colorizer/parser/names.lua +++ b/lua/colorizer/parser/names.lua @@ -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 diff --git a/lua/colorizer/sass.lua b/lua/colorizer/sass.lua index 02d5701..f4afc2c 100644 --- a/lua/colorizer/sass.lua +++ b/lua/colorizer/sass.lua @@ -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 diff --git a/lua/colorizer/tailwind.lua b/lua/colorizer/tailwind.lua index 6fe4c81..f08e31c 100644 --- a/lua/colorizer/tailwind.lua +++ b/lua/colorizer/tailwind.lua @@ -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 diff --git a/lua/colorizer/tailwind_colors.lua b/lua/colorizer/tailwind_colors.lua index 7ea7a73..9c9f470 100644 --- a/lua/colorizer/tailwind_colors.lua +++ b/lua/colorizer/tailwind_colors.lua @@ -269,6 +269,6 @@ return { ["rose-700"] = "be123c", ["rose-800"] = "9f1239", ["rose-900"] = "881337", - ["rose-950"] = "4c0519" + ["rose-950"] = "4c0519", }, } diff --git a/lua/colorizer/trie.lua b/lua/colorizer/trie.lua index a7d9994..6af5d82 100644 --- a/lua/colorizer/trie.lua +++ b/lua/colorizer/trie.lua @@ -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 diff --git a/lua/colorizer/utils.lua b/lua/colorizer/utils.lua index ae590cd..26d0a2d 100644 --- a/lua/colorizer/utils.lua +++ b/lua/colorizer/utils.lua @@ -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)) diff --git a/plugin/colorizer.lua b/plugin/colorizer.lua index 979a888..fc10a9d 100644 --- a/plugin/colorizer.lua +++ b/plugin/colorizer.lua @@ -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, {}) diff --git a/test/expectation.txt b/test/expectation.txt index 6150778..24a17bf 100644 --- a/test/expectation.txt +++ b/test/expectation.txt @@ -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 diff --git a/test/tailwind.html b/test/tailwind.html new file mode 100644 index 0000000..6610eb5 --- /dev/null +++ b/test/tailwind.html @@ -0,0 +1,275 @@ +
Prefixes
+
+ Colors +