diff options
author | Akianonymus <anonymus.aki@gmail.com> | 2022-09-04 18:32:02 +0530 |
---|---|---|
committer | Akianonymus <anonymus.aki@gmail.com> | 2022-09-06 15:06:14 +0530 |
commit | 5f7680e7e7ccad68bd9962bcbb40dfde1c3669a1 (patch) | |
tree | 0345c3393e3f64d77042224dc6b3e4672b1e901e /lua/colorizer/buffer_utils.lua | |
parent | colorizer: Make sure it works without giving any config (diff) |
Fix https://github.com/NvChad/nvim-colorizer.lua/issues/12 | Add support for tailwind colors
Three methods
normal: Use the hardcoded colors
lsp: Use lsp to fetch colors
both: Use the hardcoded colors and use lsp too if available
although this is hardcoding, but working with what we got, has all the
colors tailwind provides, atleast the prebuilt ones
for new defined colors, have to enable the lsp method
Generated using https://github.com/tailwindlabs/tailwindcss/raw/master/src/public/colors.js
and https://github.com/tailwindlabs/tailwindcss/raw/master/src/corePlugins.js
use a different namespace than default for tailwind lsp method
only try to use lsp method if attached
Misc changes
export the user_default_settings to doc
clear name space after the lines are processed for a smooth transition
cleanup some code
Diffstat (limited to 'lua/colorizer/buffer_utils.lua')
-rw-r--r-- | lua/colorizer/buffer_utils.lua | 122 |
1 files changed, 108 insertions, 14 deletions
diff --git a/lua/colorizer/buffer_utils.lua b/lua/colorizer/buffer_utils.lua index 0f8517f..d0b0faa 100644 --- a/lua/colorizer/buffer_utils.lua +++ b/lua/colorizer/buffer_utils.lua @@ -13,10 +13,14 @@ local color_is_bright = color_utils.color_is_bright local matcher_utils = require "colorizer.matcher_utils" local make_matcher = matcher_utils.make_matcher +local highlight_buffer, rehighlight_buffer +local BUFFER_LINES = {} --- Default namespace used in `highlight_buffer` and `colorizer.attach_to_buffer`. -- @see highlight_buffer -- @see colorizer.attach_to_buffer local DEFAULT_NAMESPACE = create_namespace "colorizer" +-- use a different namespace for tailwind as will be cleared if kept in Default namespace +local DEFAULT_NAMESPACE_TAILWIND = create_namespace "colorizer_tailwind" local HIGHLIGHT_NAME_PREFIX = "colorizer" --- Highlight mode which will be use to render the colour local HIGHLIGHT_MODE_NAMES = { @@ -72,6 +76,13 @@ local function create_highlight(rgb_hex, options) end local function add_highlight(options, buf, ns, data) + clear_namespace( + buf, + ns, + BUFFER_LINES[buf]["old_min"] or BUFFER_LINES[buf]["min"], + BUFFER_LINES[buf]["old_max"] or BUFFER_LINES[buf]["max"] + ) + if vim.tbl_contains({ "foreground", "background" }, options.mode) then for linenr, hls in pairs(data) do for _, hl in ipairs(hls) do @@ -90,6 +101,37 @@ local function add_highlight(options, buf, ns, data) end end +local function highlight_buffer_tailwind(buf, ns, mode, options) + -- it can take some time to actually fetch the results + -- on top of that, tailwindcss is quite slow in neovim + vim.defer_fn(function() + local opts = { textDocument = vim.lsp.util.make_text_document_params() } + --@local + ---@diagnostic disable-next-line: param-type-mismatch + vim.lsp.buf_request(buf, "textDocument/documentColor", opts, function(err, results, _, _) + if err == nil and results ~= nil then + local datas = {} + for _, color in pairs(results) do + local cur_line = color.range.start.line + local r, g, b, a = color.color.red or 0, color.color.green or 0, color.color.blue or 0, color.color.alpha or 0 + local rgb_hex = string.format("%02x%02x%02x", r * a * 255, g * a * 255, b * a * 255) + local name = create_highlight(rgb_hex, mode) + local first_col = color.range.start.character + local end_col = color.range["end"].character + + local d = datas[cur_line] or {} + table.insert(d, { name = name, range = { first_col, end_col } }) + datas[cur_line] = d + end + add_highlight(options, buf, ns, datas) + end + end) + end, 10) +end + +local TW_LSP_ATTACHED = {} +local TW_LSP_AU_CREATED = {} +local TW_LSP_AU_ID = {} --- 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`. @@ -98,7 +140,9 @@ end ---@param lines table: the lines to highlight from the buffer. ---@param line_start number: line_start should be 0-indexed ---@param options table: Configuration options as described in `setup` -local function highlight_buffer(buf, ns, lines, line_start, options) +---@param options_local table: Buffer local variables +---@return nil|boolean|number,function|nil +function highlight_buffer(buf, ns, lines, line_start, options, options_local) if buf == 0 or buf == nil then buf = api.nvim_get_current_buf() end @@ -129,19 +173,53 @@ local function highlight_buffer(buf, ns, lines, line_start, options) end end add_highlight(options, buf, ns, data) -end -local BUFFER_LINES = {} ---- Rehighlight the buffer if colorizer is active ----@param buf number: Buffer number ----@param options table: Buffer options -local function rehighlight_buffer(buf, options) - if buf == 0 or buf == nil then - buf = api.nvim_get_current_buf() + if not options.tailwind or (options.tailwind ~= "lsp" and options.tailwind ~= "both") then + return end - local ns = DEFAULT_NAMESPACE + -- create the autocmds so tailwind colours only activate when tailwindcss lsp is active + if not TW_LSP_AU_CREATED[buf] then + TW_LSP_AU_ID[buf] = {} + TW_LSP_AU_ID[buf][1] = api.nvim_create_autocmd("LspAttach", { + group = options_local.__augroup_id, + buffer = buf, + 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 + highlight_buffer_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, mode, options) + TW_LSP_ATTACHED[buf] = true + end + end + end, + }) + local function del_tailwind_stuff() + pcall(api.nvim_del_autocmd, TW_LSP_AU_ID[buf][1]) + pcall(api.nvim_del_autocmd, TW_LSP_AU_ID[buf][2]) + TW_LSP_ATTACHED[buf], TW_LSP_AU_CREATED[buf], TW_LSP_AU_ID[buf] = nil, nil, nil + end + -- make sure the autocmds are deleted after lsp server is closed + TW_LSP_AU_ID[buf][2] = api.nvim_create_autocmd("LspDetach", { + group = options_local.__augroup_id, + buffer = buf, + callback = function() + del_tailwind_stuff() + clear_namespace(buf, DEFAULT_NAMESPACE_TAILWIND, 0, -1) + end, + }) + TW_LSP_AU_CREATED[buf] = true + return DEFAULT_NAMESPACE_TAILWIND, del_tailwind_stuff + end + -- only try to do tailwindcss highlight if lsp is attached + if TW_LSP_ATTACHED[buf] then + highlight_buffer_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, mode, options) + end +end + +-- get the amount lines to highlight +local function getrow(buf) if not BUFFER_LINES[buf] then BUFFER_LINES[buf] = {} end @@ -176,15 +254,31 @@ local function rehighlight_buffer(buf, options) max = new_max end end - min = min or new_min max = max or new_max - clear_namespace(buf, ns, min, max) - local lines = buf_get_lines(buf, min, max, false) - highlight_buffer(buf, ns, lines, min, options) -- 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[buf]["old_max"] = max + BUFFER_LINES[buf]["old_min"] = min + return min, max +end + +--- Rehighlight the buffer if colorizer is active +---@param buf number: Buffer number +---@param options table: Buffer options +---@param options_local table|nil: Buffer local variables +---@return nil|boolean|number,function|nil +function rehighlight_buffer(buf, options, options_local) + if buf == 0 or buf == nil then + buf = api.nvim_get_current_buf() + end + + local ns = DEFAULT_NAMESPACE + + local min, max = getrow(buf) + local lines = buf_get_lines(buf, min, max, false) + return highlight_buffer(buf, ns, lines, min, options, options_local or {}) end --- @export |