aboutsummaryrefslogtreecommitdiff
path: root/lua/colorizer/tailwind.lua
diff options
context:
space:
mode:
authorAkianonymus <anonymus.aki@gmail.com>2022-09-14 21:05:37 +0530
committerAkianonymus <anonymus.aki@gmail.com>2022-09-14 21:16:35 +0530
commit51ed2f8a3ac33f6ec8979d0a8d05baf56d771305 (patch)
tree000f77a4935543b46ef5d5281b5387b32f1b9d22 /lua/colorizer/tailwind.lua
parentbuffer_utils: Perf improvements (diff)
Seperate tailwind stuff | Fix for neovim 0.7
Seperate the lines parsing logic in buffer_utils, upcoming multi threading parsing and processing Update docs
Diffstat (limited to 'lua/colorizer/tailwind.lua')
-rw-r--r--lua/colorizer/tailwind.lua154
1 files changed, 154 insertions, 0 deletions
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,
+}