skift.nvim/lua/skift/utils/cache.lua
2026-05-17 17:12:35 +02:00

107 lines
2.6 KiB
Lua

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