From 51ed2f8a3ac33f6ec8979d0a8d05baf56d771305 Mon Sep 17 00:00:00 2001 From: Akianonymus Date: Wed, 14 Sep 2022 21:05:37 +0530 Subject: Seperate tailwind stuff | Fix for neovim 0.7 Seperate the lines parsing logic in buffer_utils, upcoming multi threading parsing and processing Update docs --- doc/colorizer.txt | 39 +++++++ doc/index.html | 5 + doc/modules/colorizer.buffer_utils.html | 1 + doc/modules/colorizer.color_utils.html | 1 + doc/modules/colorizer.html | 1 + doc/modules/colorizer.matcher_utils.html | 1 + doc/modules/colorizer.sass.html | 1 + doc/modules/colorizer.tailwind.html | 143 ++++++++++++++++++++++++ doc/modules/colorizer.trie.html | 1 + doc/modules/utils.html | 1 + lua/colorizer/buffer_utils.lua | 185 ++++++------------------------- lua/colorizer/tailwind.lua | 154 +++++++++++++++++++++++++ 12 files changed, 383 insertions(+), 150 deletions(-) create mode 100644 doc/modules/colorizer.tailwind.html create mode 100644 lua/colorizer/tailwind.lua diff --git a/doc/colorizer.txt b/doc/colorizer.txt index 2cc2d6e..6171fbf 100644 --- a/doc/colorizer.txt +++ b/doc/colorizer.txt @@ -576,6 +576,45 @@ sass_update_variables({buf}, {line_start}, {line_end}, {lines}, {color_parser}, +============================================================================== +TAILWIND *colorizer.tailwind-introduction* + +Helper functions to parse tailwind color variables + + +============================================================================== +LUA API *colorizer.tailwind-lua-api* + +Functions: ~ + |tailwind_cleanup| - Cleanup tailwind variables and autocmd + + |tailwind_setup_lsp_colors| - highlight buffer using values returned by + tailwindcss + To see these table information, see |colorizer.buffer_utils| + + +tailwind_cleanup({buf}) *colorizer.tailwind.tailwind_cleanup* + Cleanup tailwind variables and autocmd + + Parameters: ~ + {buf} - number + + + + + *colorizer.tailwind.tailwind_setup_lsp_colors* +tailwind_setup_lsp_colors({buf}, {options}, {options_local}, {add_highlight}) + highlight buffer using values returned by tailwindcss + To see these table information, see |colorizer.buffer_utils| + + Parameters: ~ + {buf} - number + {options} - table + {options_local} - table + {add_highlight} - function + + + ============================================================================== TRIE *colorizer.trie-introduction* diff --git a/doc/index.html b/doc/index.html index 2b3efa5..5e9f21d 100644 --- a/doc/index.html +++ b/doc/index.html @@ -36,6 +36,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • @@ -68,6 +69,10 @@ colorizer.sass Helper functions to parse sass color variables + + colorizer.tailwind + Helper functions to parse tailwind color variables + colorizer.trie Trie implementation in luajit. diff --git a/doc/modules/colorizer.buffer_utils.html b/doc/modules/colorizer.buffer_utils.html index e433609..783afcc 100644 --- a/doc/modules/colorizer.buffer_utils.html +++ b/doc/modules/colorizer.buffer_utils.html @@ -45,6 +45,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • diff --git a/doc/modules/colorizer.color_utils.html b/doc/modules/colorizer.color_utils.html index f685731..0ac39db 100644 --- a/doc/modules/colorizer.color_utils.html +++ b/doc/modules/colorizer.color_utils.html @@ -43,6 +43,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • diff --git a/doc/modules/colorizer.html b/doc/modules/colorizer.html index 14b976f..df8879c 100644 --- a/doc/modules/colorizer.html +++ b/doc/modules/colorizer.html @@ -45,6 +45,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • diff --git a/doc/modules/colorizer.matcher_utils.html b/doc/modules/colorizer.matcher_utils.html index bdf0188..569884f 100644 --- a/doc/modules/colorizer.matcher_utils.html +++ b/doc/modules/colorizer.matcher_utils.html @@ -43,6 +43,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • diff --git a/doc/modules/colorizer.sass.html b/doc/modules/colorizer.sass.html index 45ec0d8..1abd56d 100644 --- a/doc/modules/colorizer.sass.html +++ b/doc/modules/colorizer.sass.html @@ -43,6 +43,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • diff --git a/doc/modules/colorizer.tailwind.html b/doc/modules/colorizer.tailwind.html new file mode 100644 index 0000000..ae4d64b --- /dev/null +++ b/doc/modules/colorizer.tailwind.html @@ -0,0 +1,143 @@ + + + + + colorizer Docs + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Module colorizer.tailwind

    +

    Helper functions to parse tailwind color variables

    +

    + +

    + + +

    Functions

    + + + + + + + + + +
    tailwind_cleanup (buf)Cleanup tailwind variables and autocmd
    tailwind_setup_lsp_colors (buf, options, options_local, add_highlight)highlight buffer using values returned by tailwindcss + To see these table information, see |colorizer.buffer_utils|
    + +
    +
    + + +

    Functions

    + +
    +
    + + tailwind_cleanup (buf) +
    +
    + Cleanup tailwind variables and autocmd + + +

    Parameters:

    +
      +
    • buf + number +
    • +
    + + + + + +
    +
    + + tailwind_setup_lsp_colors (buf, options, options_local, add_highlight) +
    +
    + highlight buffer using values returned by tailwindcss + To see these table information, see |colorizer.buffer_utils| + + +

    Parameters:

    +
      +
    • buf + number +
    • +
    • options + table +
    • +
    • options_local + table +
    • +
    • add_highlight + function +
    • +
    + + + + + +
    +
    + + +
    +
    +
    +generated by LDoc 1.4.6 +Last updated - September +
    +
    + + diff --git a/doc/modules/colorizer.trie.html b/doc/modules/colorizer.trie.html index 25cd3cb..c9433fc 100644 --- a/doc/modules/colorizer.trie.html +++ b/doc/modules/colorizer.trie.html @@ -39,6 +39,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • diff --git a/doc/modules/utils.html b/doc/modules/utils.html index 8a5479a..9170c4e 100644 --- a/doc/modules/utils.html +++ b/doc/modules/utils.html @@ -43,6 +43,7 @@
  • color_utils
  • matcher_utils
  • sass
  • +
  • tailwind
  • trie
  • utils
  • diff --git a/lua/colorizer/buffer_utils.lua b/lua/colorizer/buffer_utils.lua index 857e399..1f389c2 100644 --- a/lua/colorizer/buffer_utils.lua +++ b/lua/colorizer/buffer_utils.lua @@ -14,6 +14,10 @@ local sass = require "colorizer.sass" local sass_update_variables = sass.sass_update_variables local sass_cleanup = sass.sass_cleanup +local tailwind = require "colorizer.tailwind" +local tailwind_setup_lsp = tailwind.tailwind_setup_lsp_colors +local tailwind_cleanup = tailwind.tailwind_cleanup + local make_matcher = require("colorizer.matcher_utils").make_matcher local highlight_buffer, rehighlight_buffer @@ -22,8 +26,6 @@ local BUFFER_LINES = {} -- @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 = { @@ -33,6 +35,33 @@ local HIGHLIGHT_MODE_NAMES = { } local HIGHLIGHT_CACHE = {} +local function parse_lines(buf, lines, line_start, options) + local loop_parse_fn = make_matcher(options) + if not loop_parse_fn then + return false + end + + local data = {} + for current_linenum, line in ipairs(lines) do + current_linenum = current_linenum - 1 + line_start + data[current_linenum] = data[current_linenum] or {} + + -- Upvalues are options and current_linenum + local i = 1 + while i < #line do + local length, rgb_hex = loop_parse_fn(line, i, buf) + if length and rgb_hex then + table.insert(data[current_linenum], { rgb_hex = rgb_hex, range = { i - 1, i + length - 1 } }) + i = i + length + else + i = i + 1 + end + end + end + + return data +end + --- Clean the highlight cache local function clear_hl_cache() HIGHLIGHT_CACHE = {} @@ -107,52 +136,6 @@ local function add_highlight(options, buf, ns, data, line_start, line_end) end end -local function highlight_buffer_tailwind(buf, ns, 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, line_start, line_end = {}, nil, nil - for _, color in pairs(results) do - local cur_line = color.range.start.line - if line_start then - if cur_line < line_start then - line_start = cur_line - end - else - line_start = cur_line - end - - local end_line = color.range["end"].line - if line_end then - if end_line > line_end then - line_end = end_line - end - else - line_end = end_line - end - - 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 first_col = color.range.start.character - local end_col = color.range["end"].character - - datas[cur_line] = datas[cur_line] or {} - table.insert(datas[cur_line], { rgb_hex = rgb_hex, range = { first_col, end_col } }) - end - add_highlight(options, buf, ns, datas, line_start or 0, line_end and (line_end + 2) or -1) - end - end) - end, 10) -end - -local TW_LSP_AU_CREATED = {} -local TW_LSP_AU_ID = {} -local TW_LSP_CLIENT = {} --- 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`. @@ -171,10 +154,6 @@ function highlight_buffer(buf, ns, lines, line_start, line_end, options, options end ns = ns or DEFAULT_NAMESPACE - local loop_parse_fn = make_matcher(options) - if not loop_parse_fn then - return false, returns - end -- only update sass varibled when text is changed if options_local.__event ~= "WinScrolled" and options.sass and options.sass.enable then @@ -182,106 +161,12 @@ function highlight_buffer(buf, ns, lines, line_start, line_end, options, options sass_update_variables(buf, 0, -1, nil, make_matcher(options.sass.parsers or { css = true }), options, options_local) end - local data = {} - for current_linenum, line in ipairs(lines) do - current_linenum = current_linenum - 1 + line_start - data[current_linenum] = data[current_linenum] or {} - - -- Upvalues are options and current_linenum - local i = 1 - while i < #line do - local length, rgb_hex = loop_parse_fn(line, i, buf) - if length and rgb_hex then - table.insert(data[current_linenum], { rgb_hex = rgb_hex, range = { i - 1, i + length - 1 } }) - i = i + length - else - i = i + 1 - end - end - end + local data = parse_lines(buf, lines, line_start, options) add_highlight(options, buf, ns, data, line_start, line_end) - if not options.tailwind or (options.tailwind ~= "lsp" and options.tailwind ~= "both") then - return true, returns - end - - if not TW_LSP_CLIENT[buf] or TW_LSP_CLIENT[buf].is_stopped() then - local function del_tailwind_stuff() - TW_LSP_CLIENT[buf] = nil - end - if vim.version().minor >= 8 then - -- create the autocmds so tailwind colours only activate when tailwindcss lsp is active - 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_AU_CREATED[buf], TW_LSP_AU_ID[buf], TW_LSP_CLIENT[buf] = nil, nil, nil - end - - if not TW_LSP_AU_CREATED[buf] then - TW_LSP_AU_ID[buf], TW_LSP_AU_CREATED[buf], TW_LSP_CLIENT[buf] = {}, nil, nil - 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 - -- wait 100 ms for the first request - TW_LSP_CLIENT[buf] = client - vim.defer_fn(function() - highlight_buffer_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options) - end, 100) - end - end - 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 - end - end - - TW_LSP_CLIENT[buf] = nil - - local ok, tailwind_client = pcall(function() - return vim.lsp.get_active_clients { bufnr = buf, name = "tailwindcss" } - end) - tailwind_client = ok and tailwind_client or {} - if vim.tbl_isempty(tailwind_client) then - table.insert(returns.detach.functions, del_tailwind_stuff) - table.insert(returns.detach.ns, DEFAULT_NAMESPACE_TAILWIND) - return true, returns - end - - if not tailwind_client[1] or not tailwind_client[1].supports_method "textDocument/documentColor" then - table.insert(returns.detach.functions, del_tailwind_stuff) - table.insert(returns.detach.ns, DEFAULT_NAMESPACE_TAILWIND) - return true, returns - end - - TW_LSP_CLIENT[buf] = tailwind_client[1] - - -- wait 100 ms for the first request - vim.defer_fn(function() - highlight_buffer_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options) - end, 100) - - table.insert(returns.detach.functions, del_tailwind_stuff) - table.insert(returns.detach.ns, DEFAULT_NAMESPACE_TAILWIND) - - return true, returns - end - - -- only try to do tailwindcss highlight if lsp is attached - if TW_LSP_CLIENT[buf] then - highlight_buffer_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options) + if options.tailwind == "lsp" or options.tailwind == "both" then + tailwind_setup_lsp(buf, options, options_local, add_highlight) + table.insert(returns.detach.functions, tailwind_cleanup) end return true, returns diff --git a/lua/colorizer/tailwind.lua b/lua/colorizer/tailwind.lua new file mode 100644 index 0000000..88094f5 --- /dev/null +++ b/lua/colorizer/tailwind.lua @@ -0,0 +1,154 @@ +---Helper functions to parse tailwind color variables +--@module colorizer.tailwind +local api = vim.api + +-- use a different namespace for tailwind as will be cleared if kept in Default namespace +local DEFAULT_NAMESPACE_TAILWIND = api.nvim_create_namespace "colorizer_tailwind" + +local TAILWIND = {} + +--- Cleanup tailwind variables and autocmd +---@param buf number +local function tailwind_cleanup(buf) + pcall(api.nvim_del_autocmd, TAILWIND[buf] and TAILWIND[buf].AU_ID[1]) + pcall(api.nvim_del_autocmd, TAILWIND[buf] and TAILWIND[buf].AU_ID[2]) + api.nvim_buf_clear_namespace(buf, DEFAULT_NAMESPACE_TAILWIND, 0, -1) + TAILWIND[buf] = nil +end + +local function highlight_buffer_tailwind(buf, 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() + 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, _, _) + if err == nil and results ~= nil then + local datas, line_start, line_end = {}, nil, nil + for _, color in pairs(results) do + local cur_line = color.range.start.line + if line_start then + if cur_line < line_start then + line_start = cur_line + end + else + line_start = cur_line + end + + local end_line = color.range["end"].line + if line_end then + if end_line > line_end then + line_end = end_line + end + else + line_end = end_line + end + + 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 first_col = color.range.start.character + local end_col = color.range["end"].character + + datas[cur_line] = datas[cur_line] or {} + table.insert(datas[cur_line], { rgb_hex = rgb_hex, range = { first_col, end_col } }) + end + add_highlight(options, buf, ns, datas, line_start or 0, line_end and (line_end + 2) or -1) + end + end) + end, 10) +end + +--- highlight buffer using values returned by tailwindcss +-- To see these table information, see |colorizer.buffer_utils| +---@param buf number +---@param options table +---@param options_local table +---@param add_highlight function +local 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 {} + + if not TAILWIND[buf].CLIENT or TAILWIND[buf].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 + tailwind_cleanup(buf) + TAILWIND[buf].AU_ID[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 + -- wait 100 ms for the first request + TAILWIND[buf].CLIENT = client + vim.defer_fn(function() + highlight_buffer_tailwind(buf, 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", { + group = options_local.__augroup_id, + buffer = buf, + callback = function() + tailwind_cleanup(buf) + end, + }) + TAILWIND[buf].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) + + TAILWIND[buf].CLIENT = nil + + local ok, tailwind_client = pcall(function() + return vim.lsp.get_active_clients { bufnr = buf, name = "tailwindcss" } + end) + if not ok then + return + end + + ok = false + for _, cl in pairs(tailwind_client) do + if cl["name"] == "tailwindcss" then + tailwind_client = cl + ok = false + break + end + end + + if + vim.tbl_isempty(tailwind_client or {}) + or not tailwind_client + or not tailwind_client.supports_method + or not tailwind_client.supports_method "textDocument/documentColor" + then + return true + end + + TAILWIND[buf].CLIENT = tailwind_client + + -- wait 500 ms for the first request + vim.defer_fn(function() + highlight_buffer_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight) + end, 500) + + return true + end + + -- only try to do tailwindcss highlight if lsp is attached + if TAILWIND[buf].CLIENT then + highlight_buffer_tailwind(buf, DEFAULT_NAMESPACE_TAILWIND, options, add_highlight) + end +end + +---@export +return { + tailwind_cleanup = tailwind_cleanup, + tailwind_setup_lsp_colors = tailwind_setup_lsp_colors, +} -- cgit v1.2.3-70-g09d2