local M = {} local CACHE_VERSION = 1 local CACHE_DIR = vim.fn.stdpath("cache") .. "/skift" local SOURCE_FILES = { "lua/skift/palette.lua", "lua/skift/init.lua", "lua/skift/groups/editor.lua", "lua/skift/groups/syntax.lua", "lua/skift/groups/treesitter.lua", "lua/skift/groups/lsp.lua", "lua/skift/groups/integrations.lua", "lua/skift/utils/palette.lua", } local function function_fingerprint(fn) if type(fn) ~= "function" then return tostring(fn) end local ok, dumped = pcall(string.dump, fn) if ok and dumped then return vim.fn.sha256(dumped) end local info = debug.getinfo(fn, "S") if info and info.source then return string.format("%s:%d", info.source, info.linedefined or 0) end return tostring(fn) end local function source_fingerprint() local stamp = {} for _, pattern in ipairs(SOURCE_FILES) do local path = vim.api.nvim_get_runtime_file(pattern, false)[1] if path then local stat = vim.loop.fs_stat(path) stamp[#stamp + 1] = { file = pattern, mtime = stat and stat.mtime and stat.mtime.sec or 0, size = stat and stat.size or 0, } else stamp[#stamp + 1] = { file = pattern, mtime = 0, size = 0 } end end return stamp end local function cache_file(cache_key) return CACHE_DIR .. "/highlights-" .. cache_key .. ".json" end ---@param config Config function M.key(config) local payload = { version = CACHE_VERSION, transparent = config.transparent, bold = config.bold, italic = config.italic, italic_comments = config.italic_comments, on_colors = function_fingerprint(config.on_colors), on_highlights = function_fingerprint(config.on_highlights), sources = source_fingerprint(), } return vim.fn.sha256(vim.json.encode(payload)) end function M.read(cache_key) local path = cache_file(cache_key) if vim.fn.filereadable(path) == 0 then return nil end local ok_read, lines = pcall(vim.fn.readfile, path) if not ok_read or not lines then return nil end local raw = table.concat(lines, "\n") local ok_decode, decoded = pcall(vim.json.decode, raw) if not ok_decode then return nil end return decoded end function M.write(cache_key, payload) vim.fn.mkdir(CACHE_DIR, "p") local path = cache_file(cache_key) local encoded = vim.json.encode(payload) local ok_write = pcall(vim.fn.writefile, { encoded }, path) return ok_write end function M.clear() vim.fn.delete(CACHE_DIR, "rf") end return M