diff --git a/.github/release-please-config.json b/.github/release-please-config.json new file mode 100644 index 0000000..6cbd2bc --- /dev/null +++ b/.github/release-please-config.json @@ -0,0 +1,9 @@ +{ + "packages": { + ".": { + "extra-files": [ + "lua/zenbones/util.lua" + ] + } + } +} diff --git a/.github/release-please-manifest.json b/.github/release-please-manifest.json new file mode 100644 index 0000000..9e3120a --- /dev/null +++ b/.github/release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "4.12.0" +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9f1a8f..6cd6105 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,6 +105,8 @@ jobs: - uses: googleapis/release-please-action@v4 with: release-type: simple + config-file: .github/release-please-config.json + manifest-file: .github/release-please-manifest.json - name: tag stable versions if: ${{ steps.release.outputs.release_created }} run: | diff --git a/doc/zenbones.md b/doc/zenbones.md index 1eb6e3e..2a6c6c8 100644 --- a/doc/zenbones.md +++ b/doc/zenbones.md @@ -92,6 +92,12 @@ Set to `1` to enable compatibility mode for all colorschemes. Enabled in Vim. To enable/disable compatibility mode for a specific theme, set the variable `g:{theme}_compat` to `0` or `1`, e.g. `let g:zenbones_compat = 1`. +#### g:bones_no_cache + +Set to `true` to disable caching for all colorschemes. Only valid for Neovim. +To enable/disable caching for a specific theme, set the variable +`g:{theme}_no_cache` to `true`, e.g. `vim.g.zenbones_no_cache = true`. + ### lightline ```vim diff --git a/lua/zenbones/term.lua b/lua/zenbones/term.lua index 7ed9a81..0a970eb 100644 --- a/lua/zenbones/term.lua +++ b/lua/zenbones/term.lua @@ -24,27 +24,40 @@ function M.colors_map(p) } end +--- Get an array of hex colors in the order of g:terminal_color_*. +---@param p table +---@return table +function M.colors_array(p) + local colors = M.colors_map(p) + return { + colors.black.hex, + colors.red.hex, + colors.green.hex, + colors.yellow.hex, + colors.blue.hex, + colors.magenta.hex, + colors.cyan.hex, + colors.white.hex, + colors.bright_black.hex, + colors.bright_red.hex, + colors.bright_green.hex, + colors.bright_yellow.hex, + colors.bright_blue.hex, + colors.bright_magenta.hex, + colors.bright_cyan.hex, + colors.bright_white.hex, + } +end + --- Apply a palette to g:terminal_color_*. ---@param p table ---@return nil function M.apply_colors(p) - local colors = M.colors_map(p) - vim.g.terminal_color_0 = colors.black.hex - vim.g.terminal_color_1 = colors.red.hex - vim.g.terminal_color_2 = colors.green.hex - vim.g.terminal_color_3 = colors.yellow.hex - vim.g.terminal_color_4 = colors.blue.hex - vim.g.terminal_color_5 = colors.magenta.hex - vim.g.terminal_color_6 = colors.cyan.hex - vim.g.terminal_color_7 = colors.white.hex - vim.g.terminal_color_8 = colors.bright_black.hex - vim.g.terminal_color_9 = colors.bright_red.hex - vim.g.terminal_color_10 = colors.bright_green.hex - vim.g.terminal_color_11 = colors.bright_yellow.hex - vim.g.terminal_color_12 = colors.bright_blue.hex - vim.g.terminal_color_13 = colors.bright_magenta.hex - vim.g.terminal_color_14 = colors.bright_cyan.hex - vim.g.terminal_color_15 = colors.bright_white.hex + local colors_array = M.colors_array(p) + + for idx, color in ipairs(colors_array) do + vim.g["terminal_color_" .. idx - 1] = color + end end return M diff --git a/lua/zenbones/util.lua b/lua/zenbones/util.lua index 49e886c..4a61226 100644 --- a/lua/zenbones/util.lua +++ b/lua/zenbones/util.lua @@ -1,15 +1,112 @@ local M = {} +M.version = "4.12.0" -- x-release-please-version + --- Apply a zenbones colorscheme based on g:colors_name and &background. ---@return nil function M.apply_colorscheme() local colors_name = vim.g.colors_name + if M.is_cache_disabled(colors_name) then + M.apply_colorscheme_without_cache(colors_name) + else + M.apply_colorscheme_with_cache(colors_name) + end +end + +function M.is_cache_disabled(colors_name) + return vim.g.bones_no_cache or vim.g[colors_name .. "_no_cache"] +end + +function M.apply_colorscheme_without_cache(colors_name) package.loaded[colors_name] = nil require "lush"(require(colors_name), { force_clean = false }) local p = require(colors_name .. ".palette")[vim.o.background] require("zenbones.term").apply_colors(p) end +function M.apply_colorscheme_with_cache(global_colors_name) + -- For randombones, we should cache individual colorscheme with their real name + -- but use options from prefix "randombones" + local opts = require("zenbones.specs").get_global_config(global_colors_name, vim.o.background) + local colors_name = vim.g.randombones_colors_name or global_colors_name + local inputs = { + version = M.version, + opts = opts, + } + + local cache = M.cache.load(colors_name) + + local colors, palette + if cache and vim.deep_equal(inputs, cache.inputs) then + colors = cache.colors + palette = cache.palette + else + colors = M.compile_colorscheme(colors_name, opts) + palette = M.compile_palette(colors_name, vim.o.background) + local ok, msg = M.cache.write(colors_name, { + inputs = inputs, + colors = colors, + palette = palette, + }) + if not ok then + vim.notify("zenbones.nvim failed to cache colors: " .. msg, vim.log.levels.WARN) + end + end + + for group, attrs in pairs(colors) do + vim.api.nvim_set_hl(0, group, attrs) + end + + for idx, color in ipairs(palette) do + vim.g["terminal_color_" .. idx - 1] = color + end +end + +function M.compile_colorscheme(colors_name) + local spec = require(colors_name) + return require("lush.compiler")(spec) +end + +function M.compile_palette(colors_name, bg) + local p = require(colors_name .. ".palette")[bg] + return require("zenbones.term").colors_array(p) +end + +M.cache = {} + +function M.cache.file(colors_name) + return vim.fn.stdpath("cache") .. "/" .. colors_name .. ".msgpack" +end + +function M.cache.load(colors_name) + local ok, cache = pcall(function() + local file = io.open(M.cache.file(colors_name), "rb") + local content = file:read("*a") + file:close() + return vim.mpack.decode(content) + end) + + return ok and cache or nil +end + +function M.cache.write(colors_name, cache) + return pcall(function() + local file, msg = io.open(M.cache.file(colors_name), "wb+") + if not file then + error(msg) + end + file:write(vim.mpack.encode(cache)) + file:close() + end) +end + +function M.cache.clear() + for _, colorscheme in ipairs(M.get_colorscheme_list()) do + local path = M.cache.file(colorscheme.name) + vim.uv.fs_unlink(path) + end +end + function M.get_colorscheme_list() local file = io.open(vim.api.nvim_get_runtime_file("zenbones.json", false)[1], "r") if not file then