From c0df5b8859ca1c0944f4fde3a4aaf81d0edd8b19 Mon Sep 17 00:00:00 2001 From: spore Date: Sun, 17 May 2026 17:25:13 +0800 Subject: [PATCH 1/6] feat: cache colors --- lua/zenbones/term.lua | 22 ++++++++++ lua/zenbones/util.lua | 87 +++++++++++++++++++++++++++++++++++++- release-please-config.json | 5 +++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 release-please-config.json diff --git a/lua/zenbones/term.lua b/lua/zenbones/term.lua index 7ed9a816..376a5b67 100644 --- a/lua/zenbones/term.lua +++ b/lua/zenbones/term.lua @@ -24,6 +24,28 @@ function M.colors_map(p) } end +function M.get_colors_idx(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 diff --git a/lua/zenbones/util.lua b/lua/zenbones/util.lua index 49e886c2..f40d0dbb 100644 --- a/lua/zenbones/util.lua +++ b/lua/zenbones/util.lua @@ -1,8 +1,10 @@ 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() +function M.apply_colorscheme_without_cache() local colors_name = vim.g.colors_name package.loaded[colors_name] = nil require "lush"(require(colors_name), { force_clean = false }) @@ -10,6 +12,89 @@ function M.apply_colorscheme() require("zenbones.term").apply_colors(p) end +-- TODO add an option to opt-out caching +function M.apply_colorscheme() + local colors_name = vim.g.randombones_colors_name or vim.g.colors_name + -- TODO don't call get_global_config twice + local opts = require("zenbones.specs").get_global_config(colors_name, vim.o.background) + 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").get_colors_idx(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 diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 00000000..3ca60992 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,5 @@ +{ + "extra-files": [ + "lua/zenbones/util.lua" + ] +} From ad5241141e0ce588d5329ab4796906ded3191121 Mon Sep 17 00:00:00 2001 From: spore Date: Sun, 17 May 2026 22:37:23 +0800 Subject: [PATCH 2/6] feat: add global option `bones_no_cache` to disable cache --- doc/zenbones.md | 6 ++++++ lua/zenbones/util.lua | 24 ++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/doc/zenbones.md b/doc/zenbones.md index 1eb6e3ea..2a6c6c81 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/util.lua b/lua/zenbones/util.lua index f40d0dbb..c49fae66 100644 --- a/lua/zenbones/util.lua +++ b/lua/zenbones/util.lua @@ -4,19 +4,31 @@ 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_without_cache() +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 --- TODO add an option to opt-out caching -function M.apply_colorscheme() - local colors_name = vim.g.randombones_colors_name or vim.g.colors_name - -- TODO don't call get_global_config twice - local opts = require("zenbones.specs").get_global_config(colors_name, vim.o.background) +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, From dd2762f4124c5bf10a37a7be6ff3f413fe8f68ac Mon Sep 17 00:00:00 2001 From: spore Date: Sun, 17 May 2026 23:39:36 +0800 Subject: [PATCH 3/6] refactor: less repetition in term.lua --- lua/zenbones/term.lua | 27 +++++++++------------------ lua/zenbones/util.lua | 2 +- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/lua/zenbones/term.lua b/lua/zenbones/term.lua index 376a5b67..0a970ebb 100644 --- a/lua/zenbones/term.lua +++ b/lua/zenbones/term.lua @@ -24,7 +24,10 @@ function M.colors_map(p) } end -function M.get_colors_idx(p) +--- 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, @@ -50,23 +53,11 @@ end ---@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 c49fae66..4a61226b 100644 --- a/lua/zenbones/util.lua +++ b/lua/zenbones/util.lua @@ -69,7 +69,7 @@ end function M.compile_palette(colors_name, bg) local p = require(colors_name .. ".palette")[bg] - return require("zenbones.term").get_colors_idx(p) + return require("zenbones.term").colors_array(p) end M.cache = {} From 5260372fd3ffa38f6f929f5426526457c2927512 Mon Sep 17 00:00:00 2001 From: spore Date: Mon, 18 May 2026 23:16:57 +0800 Subject: [PATCH 4/6] chore: try to make release-please work --- .github/release-please-config.json | 9 +++++++++ .github/release-please-manifest.json | 3 +++ .github/workflows/ci.yml | 2 ++ release-please-config.json | 5 ----- 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 .github/release-please-config.json create mode 100644 .github/release-please-manifest.json delete mode 100644 release-please-config.json diff --git a/.github/release-please-config.json b/.github/release-please-config.json new file mode 100644 index 00000000..6cbd2bc7 --- /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 00000000..9e3120ae --- /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 f9f1a8f1..6cd6105f 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/release-please-config.json b/release-please-config.json deleted file mode 100644 index 3ca60992..00000000 --- a/release-please-config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extra-files": [ - "lua/zenbones/util.lua" - ] -} From f747512b92c347e0f4471ff29064af8c779dbf17 Mon Sep 17 00:00:00 2001 From: spore Date: Sat, 8 Aug 2026 11:27:39 +0800 Subject: [PATCH 5/6] fix: add background color to cache key --- lua/zenbones/util.lua | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lua/zenbones/util.lua b/lua/zenbones/util.lua index 4a61226b..e6388b67 100644 --- a/lua/zenbones/util.lua +++ b/lua/zenbones/util.lua @@ -34,7 +34,7 @@ function M.apply_colorscheme_with_cache(global_colors_name) opts = opts, } - local cache = M.cache.load(colors_name) + local cache = M.cache.load(colors_name, vim.o.background) local colors, palette if cache and vim.deep_equal(inputs, cache.inputs) then @@ -43,7 +43,7 @@ function M.apply_colorscheme_with_cache(global_colors_name) 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, { + local ok, msg = M.cache.write(colors_name, vim.o.background, { inputs = inputs, colors = colors, palette = palette, @@ -63,6 +63,7 @@ function M.apply_colorscheme_with_cache(global_colors_name) end function M.compile_colorscheme(colors_name) + package.loaded[colors_name] = nil local spec = require(colors_name) return require("lush.compiler")(spec) end @@ -74,13 +75,13 @@ end M.cache = {} -function M.cache.file(colors_name) - return vim.fn.stdpath("cache") .. "/" .. colors_name .. ".msgpack" +function M.cache.file(colors_name, background) + return vim.fn.stdpath("cache") .. "/" .. colors_name .. "_" .. background .. ".msgpack" end -function M.cache.load(colors_name) +function M.cache.load(colors_name, background) local ok, cache = pcall(function() - local file = io.open(M.cache.file(colors_name), "rb") + local file = io.open(M.cache.file(colors_name, background), "rb") local content = file:read("*a") file:close() return vim.mpack.decode(content) @@ -89,9 +90,9 @@ function M.cache.load(colors_name) return ok and cache or nil end -function M.cache.write(colors_name, cache) +function M.cache.write(colors_name, background, cache) return pcall(function() - local file, msg = io.open(M.cache.file(colors_name), "wb+") + local file, msg = io.open(M.cache.file(colors_name, background), "wb+") if not file then error(msg) end @@ -102,8 +103,8 @@ 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) + vim.uv.fs_unlink(M.cache.file(colorscheme.name, "dark")) + vim.uv.fs_unlink(M.cache.file(colorscheme.name, "light")) end end From bc982d86126f41c6ef7aadf189c4e70f57ee19bf Mon Sep 17 00:00:00 2001 From: spore Date: Sat, 8 Aug 2026 11:37:34 +0800 Subject: [PATCH 6/6] fix: only read from randombones when it's active fix switching from randombones to other colors --- lua/zenbones/util.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lua/zenbones/util.lua b/lua/zenbones/util.lua index e6388b67..08b0f6af 100644 --- a/lua/zenbones/util.lua +++ b/lua/zenbones/util.lua @@ -28,7 +28,12 @@ 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 colors_name + if global_colors_name == "randombones" then + colors_name = vim.g.randombones_colors_name + else + colors_name = global_colors_name + end local inputs = { version = M.version, opts = opts,