diff options
| author | t <t@tjp.lol> | 2026-09-20 13:08:46 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-09-20 13:10:59 -0600 |
| commit | efbac44a016258fe59d5d880accfb14d2c234d2d (patch) | |
| tree | caa627ecb419cb73c689053cffa9dff4f517c6c4 | |
Some popular color themes, packaged up as a panto extension
| -rw-r--r-- | LICENSE | 18 | ||||
| -rw-r--r-- | README.md | 97 | ||||
| -rw-r--r-- | _selfcheck.lua | 82 | ||||
| -rw-r--r-- | mise.toml | 32 | ||||
| -rw-r--r-- | panto-popular-themes-0.1.0-1.rockspec | 30 | ||||
| -rw-r--r-- | panto-popular-themes/init.lua | 548 | ||||
| -rw-r--r-- | scripts/verify-against-core.lua | 50 |
7 files changed, 857 insertions, 0 deletions
@@ -0,0 +1,18 @@ +MIT License + +Copyright (c) 2026 Travis Parker + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f716ae8 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +# panto-popular-themes + +`themes.popular` is a small, pure-Lua [pantograph](https://github.com/travisp/pantograph) +extension. It registers the 19 popular palettes currently built into Panto as +well as three Kanagawa variants, using the same role-to-SGR derivation as the +core. + +## Install + +Add the rock to Panto's extension list: + +```toml +[extensions] +rocks = ["panto-popular-themes"] +``` + +The extension is named `themes.popular`; theme names are case-sensitive. + +## Themes + +- Tokyo Night +- Catppuccin Mocha +- Gruvbox Dark +- Solarized Light +- Solarized Dark +- Nord +- Dracula +- Tokyo Storm +- Tokyo Moon +- Tokyo Day +- Catppuccin Latte +- Catppuccin Frappe +- Catppuccin Macchiato +- Gruvbox Dark Hard +- Gruvbox Dark Soft +- Gruvbox Light +- Gruvbox Light Hard +- Gruvbox Light Soft +- Dracula Soft +- Kanagawa Wave +- Kanagawa Dragon +- Kanagawa Lotus + +## Provenance and mapping + +The first 19 palettes are faithful ports of the data and role derivation in +`src/tui_theme.zig` (Tokyo Night 270–290, Catppuccin Mocha 291–311, +Gruvbox Dark 312–332, Solarized Light 333–351, Solarized Dark 352–371, +Nord 372–394, Dracula 395–416, Tokyo Storm 417–437, Tokyo Moon 438–458, +Tokyo Day 459–479, Catppuccin Latte 480–500, Catppuccin Frappe 501–521, +Catppuccin Macchiato 522–542, Gruvbox Dark Hard 543–563, Gruvbox Dark +Soft 564–584, Gruvbox Light 585–605, Gruvbox Light Hard 606–626, +Gruvbox Light Soft 627–647, Dracula Soft 648–666; derivation +`makePalette` 1046–1105). Their source pins are the ones documented by Panto: + +- Tokyo Night: [`folke/tokyonight.nvim` at `cdc07ac`](https://github.com/folke/tokyonight.nvim/tree/cdc07ac78467a233fd62c493de29a17e0cf2b2b6) +- Catppuccin: [`catppuccin/nvim` at `edefef7`](https://github.com/catppuccin/nvim/tree/edefef779ab08ce1a4a404713e3012b0d202bd35) +- Gruvbox: [`ellisonleao/gruvbox.nvim` 2.0.0 at `61b0b3b`](https://github.com/ellisonleao/gruvbox.nvim/blob/61b0b3be2f0cfd521667403a0367298144d6c165/lua/gruvbox.lua) +- Solarized: [`maxmx03/solarized.nvim` 3.6.0 at `c0dfe1c`](https://github.com/maxmx03/solarized.nvim/tree/c0dfe1cbfabd93b546baf5f1408f5df7e02e2050) +- Nord: [`nordtheme/vim` at `f13f5df`](https://github.com/nordtheme/vim/blob/f13f5dfbb784deddbc1d8195f34dfd9ec73e2295/colors/nord.vim) +- Dracula: [`Mofiqul/dracula.nvim` at `ae752c1`](https://github.com/Mofiqul/dracula.nvim/tree/ae752c13e95fb7c5f58da4b5123cb804ea7568ee) + +Kanagawa is taken from the primary [`rebelot/kanagawa.nvim`](https://github.com/rebelot/kanagawa.nvim) +repository at pinned commit +[`bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3`](https://github.com/rebelot/kanagawa.nvim/tree/bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3), +using its [`colors.lua`](https://raw.githubusercontent.com/rebelot/kanagawa.nvim/bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3/lua/kanagawa/colors.lua) +and [`themes.lua`](https://raw.githubusercontent.com/rebelot/kanagawa.nvim/bb85e4bfc8d89b0e62c8fa53ccdd13d12e2f77b3/lua/kanagawa/themes.lua). +Wave, Dragon, and Lotus map Normal foreground/background, Comment, semantic +syntax groups, NormalFloat, Title/Directory, and diagnostics into Panto's +17-color palette. Kanagawa authors real `DiffAdd`/`DiffDelete` backgrounds, +so those are retained; the 20% canvas/status tint is used only when a source +palette does not provide a diff background. + +As in core, each palette emits all 40 role SGR strings and `reset = ESC[0m`. +Activation first performs a read-only lookup for each name and registers only +names that are not already present. This makes activating the extension +alongside Panto's built-ins or a third-party palette safe: any existing +identical or different registration wins, while malformed values for a new +registration still raise. + +The stock `panto` palette and Panto's five original palettes—Tidepool Tumble, +Mossmallow, Peachy Pudding, Plum Pips, and Gilded Inkblot—stay in core and are +not registered here. + +## Development + +```sh +panto lua _selfcheck.lua +PANTOGRAPH_DIR="${PANTOGRAPH_DIR:-../pantograph}" +REPO_DIR="$(pwd)" +(cd "$PANTOGRAPH_DIR" && panto lua "$REPO_DIR/scripts/verify-against-core.lua") +``` + +The second check uses the real Panto theme registry: it compares every role +in the extension's computed snapshots with the 19 corresponding core snapshots, +reporting the theme and role for any byte mismatch, then activates the +extension to validate registration of the three Kanagawa additions. diff --git a/_selfcheck.lua b/_selfcheck.lua new file mode 100644 index 0000000..29f36de --- /dev/null +++ b/_selfcheck.lua @@ -0,0 +1,82 @@ +-- Self-check for themes.popular. Run with: panto lua _selfcheck.lua + +local here = debug.getinfo(1, "S").source:match("^@(.*)/[^/]+$") or "." +package.path = here .. "/?.lua;" .. package.path + +local roles = { + "dim", "assistant", "user", "tool", "footer", "tool_text", + "tool_pending", "tool_success", "tool_error", "compaction_header", + "thinking_header", "cursor", "err", "welcome", "waiting_peak", + "waiting_near", "waiting_far", "err_diff", "add_diff", "thinking", + "compaction", "user_bg", "tool_pending_bg", "tool_success_bg", + "tool_error_bg", "diff_remove_bg", "diff_add_bg", "user_text", + "tool_header", "canvas_fg", "canvas_bg", "syntax_base", + "syntax_comment", "syntax_string", "syntax_number", "syntax_keyword", + "syntax_function", "syntax_type", "syntax_variable", "syntax_tag", +} + +local names = { + "Tokyo Night", "Catppuccin Mocha", "Gruvbox Dark", "Solarized Light", + "Solarized Dark", "Nord", "Dracula", "Tokyo Storm", "Tokyo Moon", + "Tokyo Day", "Catppuccin Latte", "Catppuccin Frappe", + "Catppuccin Macchiato", "Gruvbox Dark Hard", "Gruvbox Dark Soft", + "Gruvbox Light", "Gruvbox Light Hard", "Gruvbox Light Soft", + "Dracula Soft", "Kanagawa Wave", "Kanagawa Dragon", "Kanagawa Lotus", +} + +local function copy(t) + local out = {} + for k, v in pairs(t) do out[k] = v end + return out +end + +local registered = {} +package.loaded["panto"] = { + ext = { + style = function(name, values) + assert(type(name) == "string") + assert(type(values) == "table", "registration values for " .. name) + local old = registered[name] + if old then + for k, v in pairs(values) do + assert(old[k] == v, "conflicting re-registration for " .. name .. ": " .. k) + end + else + registered[name] = copy(values) + end + end, + }, +} + +local entry = require("panto-popular-themes.init") +assert(entry.name == "themes.popular", "entry name") +assert(type(entry.activate) == "function", "entry activate") +entry.activate() + +local count = 0 +for name in pairs(registered) do count = count + 1 end +assert(count == 22, "expected 22 themes, got " .. count) +for _, name in ipairs(names) do + local values = registered[name] + assert(values, "missing theme " .. name) + for _, role in ipairs(roles) do + assert(type(values[role]) == "string", name .. " missing role " .. role) + end + assert(values.reset == "\27[0m", name .. " reset") +end + +local function eq(name, role, expected) + assert(registered[name][role] == expected, + name .. "." .. role .. " was " .. tostring(registered[name][role]) .. + ", expected " .. expected) +end + +eq("Tokyo Night", "tool", "\27[38;2;122;162;247m") +eq("Tokyo Night", "diff_add_bg", "\27[48;2;36;62;74m") +eq("Solarized Light", "diff_add_bg", "\27[48;2;229;227;181m") +eq("Kanagawa Lotus", "canvas_bg", "\27[48;2;242;236;188m") +eq("Kanagawa Lotus", "syntax_tag", "\27[38;2;102;147;191m") + +eq("Kanagawa Wave", "reset", "\27[0m") + +print("selfcheck: OK") diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..1de7ca9 --- /dev/null +++ b/mise.toml @@ -0,0 +1,32 @@ +# Release plumbing. `mise run version <x.y.z>` rewrites the rockspec. + +[tasks.check] +description = "Run the self-check inside panto's interpreter" +dir = "{{config_root}}" +run = "panto lua _selfcheck.lua" + +[tasks.verify] +description = "Compare moved themes against Panto core" +dir = "{{config_root}}" +run = ''' +set -eu +PANTOGRAPH_DIR="${PANTOGRAPH_DIR:-../pantograph}" +(cd "$PANTOGRAPH_DIR" && panto lua "{{config_root}}/scripts/verify-against-core.lua") +''' + +[tasks.version] +description = "Rewrite the rockspec for a version (then commit it)" +dir = "{{config_root}}" +run = ''' +set -eu +NEW="{{arg(name='version')}}" +SPEC="$(ls -1 ./*.rockspec)" +PKG="$(sed -n 's/^package = "\\(.*\\)"/\\1/p' "$SPEC")" +NEWSPEC="./$PKG-$NEW-1.rockspec" +TMP="$(mktemp)" +sed -e "s/^version = \\\".*\\\"/version = \\\"$NEW-1\\\"/" \\\ + -e "s/^\\( *\\)tag = \\\"v[^\\\"]*\\\"/\\1tag = \\\"v$NEW\\\"/" "$SPEC" > "$TMP" +mv "$TMP" "$NEWSPEC" +[ "$SPEC" = "$NEWSPEC" ] || rm -f "$SPEC" +luarocks lint "$NEWSPEC" +''' diff --git a/panto-popular-themes-0.1.0-1.rockspec b/panto-popular-themes-0.1.0-1.rockspec new file mode 100644 index 0000000..10876e2 --- /dev/null +++ b/panto-popular-themes-0.1.0-1.rockspec @@ -0,0 +1,30 @@ +rockspec_format = "3.0" +package = "panto-popular-themes" +version = "0.1.0-1" + +source = { + url = "git+https://code.tjp.lol/panto-popular-themes.git", + tag = "v0.1.0", +} + +description = { + summary = "Popular terminal themes for pantograph", + detailed = [[ +An out-of-tree panto extension registering the popular palettes shipped by +pantograph, plus Kanagawa Wave, Dragon, and Lotus. +]], + homepage = "https://code.tjp.lol/panto-popular-themes", + license = "MIT", + labels = { "panto", "pantograph", "theme", "themes", "terminal" }, +} + +dependencies = { + "lua >= 5.1", +} + +build = { + type = "builtin", + modules = { + ["panto-popular-themes"] = "panto-popular-themes/init.lua", + }, +} diff --git a/panto-popular-themes/init.lua b/panto-popular-themes/init.lua new file mode 100644 index 0000000..51f3ca5 --- /dev/null +++ b/panto-popular-themes/init.lua @@ -0,0 +1,548 @@ +-- Popular terminal palettes for pantograph. The first 19 entries are copied +-- from pantograph/src/tui_theme.zig; the final three are Kanagawa reductions. +-- Activation probes panto.ext.style(name) before registering so an existing +-- core or third-party theme wins without hiding validation errors. + +local palettes = { + { name = 'Tokyo Night', palette = { + canvas_fg = { r = 0xc0, g = 0xca, b = 0xf5 }, + canvas_bg = { r = 0x1a, g = 0x1b, b = 0x26 }, + surface = { r = 0x16, g = 0x16, b = 0x1e }, + accent = { r = 0x7a, g = 0xa2, b = 0xf7 }, + muted = { r = 0x56, g = 0x5f, b = 0x89 }, + success = { r = 0x73, g = 0xda, b = 0xca }, + err = { r = 0xdb, g = 0x4b, b = 0x4b }, + warn = { r = 0xe0, g = 0xaf, b = 0x68 }, + purple = { r = 0xbb, g = 0x9a, b = 0xf7 }, + secondary = { r = 0x7d, g = 0xcf, b = 0xff }, + syntax_string = { r = 0x9e, g = 0xce, b = 0x6a }, + syntax_number = { r = 0xff, g = 0x9e, b = 0x64 }, + syntax_keyword = { r = 0x9d, g = 0x7c, b = 0xd8 }, + syntax_function = { r = 0x7a, g = 0xa2, b = 0xf7 }, + syntax_type = { r = 0x2a, g = 0xc3, b = 0xde }, + syntax_variable = { r = 0xc0, g = 0xca, b = 0xf5 }, + syntax_tag = { r = 0xbb, g = 0x9a, b = 0xf7 }, + diff_add_bg = { r = 0x24, g = 0x3e, b = 0x4a }, + diff_remove_bg = { r = 0x4a, g = 0x27, b = 0x2f }, + } }, + { name = 'Catppuccin Mocha', palette = { + canvas_fg = { r = 0xcd, g = 0xd6, b = 0xf4 }, + canvas_bg = { r = 0x1e, g = 0x1e, b = 0x2e }, + surface = { r = 0x18, g = 0x18, b = 0x25 }, + accent = { r = 0x89, g = 0xb4, b = 0xfa }, + muted = { r = 0x93, g = 0x99, b = 0xb2 }, + success = { r = 0x94, g = 0xe2, b = 0xd5 }, + err = { r = 0xf3, g = 0x8b, b = 0xa8 }, + warn = { r = 0xf9, g = 0xe2, b = 0xaf }, + purple = { r = 0xcb, g = 0xa6, b = 0xf7 }, + secondary = { r = 0x89, g = 0xdc, b = 0xeb }, + syntax_string = { r = 0xa6, g = 0xe3, b = 0xa1 }, + syntax_number = { r = 0xfa, g = 0xb3, b = 0x87 }, + syntax_keyword = { r = 0xcb, g = 0xa6, b = 0xf7 }, + syntax_function = { r = 0x89, g = 0xb4, b = 0xfa }, + syntax_type = { r = 0xf9, g = 0xe2, b = 0xaf }, + syntax_variable = { r = 0xcd, g = 0xd6, b = 0xf4 }, + syntax_tag = { r = 0x89, g = 0xb4, b = 0xfa }, + diff_add_bg = { r = 0x36, g = 0x41, b = 0x43 }, + diff_remove_bg = { r = 0x44, g = 0x32, b = 0x44 }, + } }, + { name = 'Gruvbox Dark', palette = { + canvas_fg = { r = 0xeb, g = 0xdb, b = 0xb2 }, + canvas_bg = { r = 0x28, g = 0x28, b = 0x28 }, + surface = { r = 0x3c, g = 0x38, b = 0x36 }, + accent = { r = 0x83, g = 0xa5, b = 0x98 }, + muted = { r = 0x92, g = 0x83, b = 0x74 }, + success = { r = 0xb8, g = 0xbb, b = 0x26 }, + err = { r = 0xfb, g = 0x49, b = 0x34 }, + warn = { r = 0xfa, g = 0xbd, b = 0x2f }, + purple = { r = 0xd3, g = 0x86, b = 0x9b }, + secondary = { r = 0x8e, g = 0xc0, b = 0x7c }, + syntax_string = { r = 0xb8, g = 0xbb, b = 0x26 }, + syntax_number = { r = 0xd3, g = 0x86, b = 0x9b }, + syntax_keyword = { r = 0xfb, g = 0x49, b = 0x34 }, + syntax_function = { r = 0xb8, g = 0xbb, b = 0x26 }, + syntax_type = { r = 0xfa, g = 0xbd, b = 0x2f }, + syntax_variable = { r = 0xeb, g = 0xdb, b = 0xb2 }, + syntax_tag = { r = 0xfe, g = 0x80, b = 0x19 }, + diff_add_bg = { r = 0x62, g = 0x69, b = 0x3e }, + diff_remove_bg = { r = 0x72, g = 0x25, b = 0x29 }, + } }, + { name = 'Solarized Light', palette = { + canvas_fg = { r = 0x65, g = 0x7b, b = 0x83 }, + canvas_bg = { r = 0xfd, g = 0xf6, b = 0xe3 }, + surface = { r = 0xfb, g = 0xf3, b = 0xdb }, + accent = { r = 0x26, g = 0x8b, b = 0xd2 }, + muted = { r = 0x93, g = 0xa1, b = 0xa1 }, + success = { r = 0x85, g = 0x99, b = 0x00 }, + err = { r = 0xdc, g = 0x32, b = 0x2f }, + warn = { r = 0xb5, g = 0x89, b = 0x00 }, + purple = { r = 0xd3, g = 0x36, b = 0x82 }, + secondary = { r = 0x2a, g = 0xa1, b = 0x98 }, + syntax_string = { r = 0x2a, g = 0xa1, b = 0x98 }, + syntax_number = { r = 0xd3, g = 0x36, b = 0x82 }, + syntax_keyword = { r = 0x58, g = 0x6e, b = 0x75 }, + syntax_function = { r = 0x26, g = 0x8b, b = 0xd2 }, + syntax_type = { r = 0xb5, g = 0x89, b = 0x00 }, + syntax_variable = { r = 0x26, g = 0x8b, b = 0xd2 }, + syntax_tag = { r = 0x26, g = 0x8b, b = 0xd2 }, + } }, + { name = 'Solarized Dark', palette = { + canvas_fg = { r = 0x83, g = 0x94, b = 0x96 }, + canvas_bg = { r = 0x00, g = 0x2b, b = 0x36 }, + surface = { r = 0x00, g = 0x27, b = 0x31 }, + accent = { r = 0x26, g = 0x8b, b = 0xd2 }, + muted = { r = 0x58, g = 0x6e, b = 0x75 }, + success = { r = 0x85, g = 0x99, b = 0x00 }, + err = { r = 0xdc, g = 0x32, b = 0x2f }, + warn = { r = 0xb5, g = 0x89, b = 0x00 }, + purple = { r = 0x6c, g = 0x71, b = 0xc4 }, + secondary = { r = 0x2a, g = 0xa1, b = 0x98 }, + syntax_string = { r = 0x2a, g = 0xa1, b = 0x98 }, + syntax_number = { r = 0x6c, g = 0x71, b = 0xc4 }, + syntax_keyword = { r = 0x93, g = 0xa1, b = 0xa1 }, + syntax_function = { r = 0x26, g = 0x8b, b = 0xd2 }, + syntax_type = { r = 0xcb, g = 0x4b, b = 0x16 }, + syntax_variable = { r = 0x26, g = 0x8b, b = 0xd2 }, + syntax_tag = { r = 0x26, g = 0x8b, b = 0xd2 }, + } }, + { name = 'Nord', palette = { + canvas_fg = { r = 0xd8, g = 0xde, b = 0xe9 }, + canvas_bg = { r = 0x2e, g = 0x34, b = 0x40 }, + surface = { r = 0x43, g = 0x4c, b = 0x5e }, + accent = { r = 0x88, g = 0xc0, b = 0xd0 }, + muted = { r = 0x61, g = 0x6e, b = 0x88 }, + success = { r = 0xa3, g = 0xbe, b = 0x8c }, + err = { r = 0xbf, g = 0x61, b = 0x6a }, + warn = { r = 0xeb, g = 0xcb, b = 0x8b }, + purple = { r = 0xb4, g = 0x8e, b = 0xad }, + secondary = { r = 0x5e, g = 0x81, b = 0xac }, + syntax_string = { r = 0xa3, g = 0xbe, b = 0x8c }, + syntax_number = { r = 0xb4, g = 0x8e, b = 0xad }, + syntax_keyword = { r = 0x81, g = 0xa1, b = 0xc1 }, + syntax_function = { r = 0x88, g = 0xc0, b = 0xd0 }, + syntax_type = { r = 0x81, g = 0xa1, b = 0xc1 }, + syntax_variable = { r = 0xd8, g = 0xde, b = 0xe9 }, + syntax_tag = { r = 0xd8, g = 0xde, b = 0xe9 }, + } }, + { name = 'Dracula', palette = { + canvas_fg = { r = 0xf8, g = 0xf8, b = 0xf2 }, + canvas_bg = { r = 0x28, g = 0x2a, b = 0x36 }, + surface = { r = 0x21, g = 0x22, b = 0x2c }, + accent = { r = 0x8b, g = 0xe9, b = 0xfd }, + muted = { r = 0x62, g = 0x72, b = 0xa4 }, + success = { r = 0x50, g = 0xfa, b = 0x7b }, + err = { r = 0xff, g = 0x55, b = 0x55 }, + warn = { r = 0xf1, g = 0xfa, b = 0x8c }, + purple = { r = 0xbd, g = 0x93, b = 0xf9 }, + secondary = { r = 0xff, g = 0x79, b = 0xc6 }, + syntax_string = { r = 0xf1, g = 0xfa, b = 0x8c }, + syntax_number = { r = 0xbd, g = 0x93, b = 0xf9 }, + syntax_keyword = { r = 0xff, g = 0x79, b = 0xc6 }, + syntax_function = { r = 0x50, g = 0xfa, b = 0x7b }, + syntax_type = { r = 0xa4, g = 0xff, b = 0xff }, + syntax_variable = { r = 0xf8, g = 0xf8, b = 0xf2 }, + syntax_tag = { r = 0x8b, g = 0xe9, b = 0xfd }, + } }, + { name = 'Tokyo Storm', palette = { + canvas_fg = { r = 0xc0, g = 0xca, b = 0xf5 }, + canvas_bg = { r = 0x24, g = 0x28, b = 0x3b }, + surface = { r = 0x1f, g = 0x23, b = 0x35 }, + accent = { r = 0x7a, g = 0xa2, b = 0xf7 }, + muted = { r = 0x56, g = 0x5f, b = 0x89 }, + success = { r = 0x73, g = 0xda, b = 0xca }, + err = { r = 0xdb, g = 0x4b, b = 0x4b }, + warn = { r = 0xe0, g = 0xaf, b = 0x68 }, + purple = { r = 0xbb, g = 0x9a, b = 0xf7 }, + secondary = { r = 0x7d, g = 0xcf, b = 0xff }, + syntax_string = { r = 0x9e, g = 0xce, b = 0x6a }, + syntax_number = { r = 0xff, g = 0x9e, b = 0x64 }, + syntax_keyword = { r = 0x9d, g = 0x7c, b = 0xd8 }, + syntax_function = { r = 0x7a, g = 0xa2, b = 0xf7 }, + syntax_type = { r = 0x2a, g = 0xc3, b = 0xde }, + syntax_variable = { r = 0xc0, g = 0xca, b = 0xf5 }, + syntax_tag = { r = 0xbb, g = 0x9a, b = 0xf7 }, + diff_add_bg = { r = 0x2b, g = 0x48, b = 0x5a }, + diff_remove_bg = { r = 0x52, g = 0x31, b = 0x3f }, + } }, + { name = 'Tokyo Moon', palette = { + canvas_fg = { r = 0xc8, g = 0xd3, b = 0xf5 }, + canvas_bg = { r = 0x22, g = 0x24, b = 0x36 }, + surface = { r = 0x1e, g = 0x20, b = 0x30 }, + accent = { r = 0x82, g = 0xaa, b = 0xff }, + muted = { r = 0x63, g = 0x6d, b = 0xa6 }, + success = { r = 0x4f, g = 0xd6, b = 0xbe }, + err = { r = 0xc5, g = 0x3b, b = 0x53 }, + warn = { r = 0xff, g = 0xc7, b = 0x77 }, + purple = { r = 0xc0, g = 0x99, b = 0xff }, + secondary = { r = 0x86, g = 0xe1, b = 0xfc }, + syntax_string = { r = 0xc3, g = 0xe8, b = 0x8d }, + syntax_number = { r = 0xff, g = 0x96, b = 0x6c }, + syntax_keyword = { r = 0xfc, g = 0xa7, b = 0xea }, + syntax_function = { r = 0x82, g = 0xaa, b = 0xff }, + syntax_type = { r = 0x65, g = 0xbc, b = 0xff }, + syntax_variable = { r = 0xc8, g = 0xd3, b = 0xf5 }, + syntax_tag = { r = 0xc0, g = 0x99, b = 0xff }, + diff_add_bg = { r = 0x2a, g = 0x45, b = 0x56 }, + diff_remove_bg = { r = 0x4b, g = 0x2a, b = 0x3d }, + } }, + { name = 'Tokyo Day', palette = { + canvas_fg = { r = 0x37, g = 0x60, b = 0xbf }, + canvas_bg = { r = 0xe1, g = 0xe2, b = 0xe7 }, + surface = { r = 0xd0, g = 0xd5, b = 0xe3 }, + accent = { r = 0x2e, g = 0x7d, b = 0xe9 }, + muted = { r = 0x84, g = 0x8c, b = 0xb5 }, + success = { r = 0x38, g = 0x70, b = 0x68 }, + err = { r = 0xc6, g = 0x43, b = 0x43 }, + warn = { r = 0x8c, g = 0x6c, b = 0x3e }, + purple = { r = 0x98, g = 0x54, b = 0xf1 }, + secondary = { r = 0x00, g = 0x71, b = 0x97 }, + syntax_string = { r = 0x58, g = 0x75, b = 0x39 }, + syntax_number = { r = 0xb1, g = 0x5c, b = 0x00 }, + syntax_keyword = { r = 0x78, g = 0x47, b = 0xbd }, + syntax_function = { r = 0x2e, g = 0x7d, b = 0xe9 }, + syntax_type = { r = 0x18, g = 0x80, b = 0x92 }, + syntax_variable = { r = 0x37, g = 0x60, b = 0xbf }, + syntax_tag = { r = 0x98, g = 0x54, b = 0xf1 }, + diff_add_bg = { r = 0xb7, g = 0xce, b = 0xd5 }, + diff_remove_bg = { r = 0xda, g = 0xba, b = 0xbe }, + } }, + { name = 'Catppuccin Latte', palette = { + canvas_fg = { r = 0x4c, g = 0x4f, b = 0x69 }, + canvas_bg = { r = 0xef, g = 0xf1, b = 0xf5 }, + surface = { r = 0xe6, g = 0xe9, b = 0xef }, + accent = { r = 0x1e, g = 0x66, b = 0xf5 }, + muted = { r = 0x7c, g = 0x7f, b = 0x93 }, + success = { r = 0x17, g = 0x92, b = 0x99 }, + err = { r = 0xd2, g = 0x0f, b = 0x39 }, + warn = { r = 0xdf, g = 0x8e, b = 0x1d }, + purple = { r = 0x88, g = 0x39, b = 0xef }, + secondary = { r = 0x04, g = 0xa5, b = 0xe5 }, + syntax_string = { r = 0x40, g = 0xa0, b = 0x2b }, + syntax_number = { r = 0xfe, g = 0x64, b = 0x0b }, + syntax_keyword = { r = 0x88, g = 0x39, b = 0xef }, + syntax_function = { r = 0x1e, g = 0x66, b = 0xf5 }, + syntax_type = { r = 0xdf, g = 0x8e, b = 0x1d }, + syntax_variable = { r = 0x4c, g = 0x4f, b = 0x69 }, + syntax_tag = { r = 0x1e, g = 0x66, b = 0xf5 }, + diff_add_bg = { r = 0xd0, g = 0xe2, b = 0xd1 }, + diff_remove_bg = { r = 0xea, g = 0xc8, b = 0xd3 }, + } }, + { name = 'Catppuccin Frappe', palette = { + canvas_fg = { r = 0xc6, g = 0xd0, b = 0xf5 }, + canvas_bg = { r = 0x30, g = 0x34, b = 0x46 }, + surface = { r = 0x29, g = 0x2c, b = 0x3c }, + accent = { r = 0x8c, g = 0xaa, b = 0xee }, + muted = { r = 0x94, g = 0x9c, b = 0xbb }, + success = { r = 0x81, g = 0xc8, b = 0xbe }, + err = { r = 0xe7, g = 0x82, b = 0x84 }, + warn = { r = 0xe5, g = 0xc8, b = 0x90 }, + purple = { r = 0xca, g = 0x9e, b = 0xe6 }, + secondary = { r = 0x99, g = 0xd1, b = 0xdb }, + syntax_string = { r = 0xa6, g = 0xd1, b = 0x89 }, + syntax_number = { r = 0xef, g = 0x9f, b = 0x76 }, + syntax_keyword = { r = 0xca, g = 0x9e, b = 0xe6 }, + syntax_function = { r = 0x8c, g = 0xaa, b = 0xee }, + syntax_type = { r = 0xe5, g = 0xc8, b = 0x90 }, + syntax_variable = { r = 0xc6, g = 0xd0, b = 0xf5 }, + syntax_tag = { r = 0x8c, g = 0xaa, b = 0xee }, + diff_add_bg = { r = 0x45, g = 0x50, b = 0x52 }, + diff_remove_bg = { r = 0x51, g = 0x42, b = 0x51 }, + } }, + { name = 'Catppuccin Macchiato', palette = { + canvas_fg = { r = 0xca, g = 0xd3, b = 0xf5 }, + canvas_bg = { r = 0x24, g = 0x27, b = 0x3a }, + surface = { r = 0x1e, g = 0x20, b = 0x30 }, + accent = { r = 0x8a, g = 0xad, b = 0xf4 }, + muted = { r = 0x93, g = 0x9a, b = 0xb7 }, + success = { r = 0x8b, g = 0xd5, b = 0xca }, + err = { r = 0xed, g = 0x87, b = 0x96 }, + warn = { r = 0xee, g = 0xd4, b = 0x9f }, + purple = { r = 0xc6, g = 0xa0, b = 0xf6 }, + secondary = { r = 0x91, g = 0xd7, b = 0xe3 }, + syntax_string = { r = 0xa6, g = 0xda, b = 0x95 }, + syntax_number = { r = 0xf5, g = 0xa9, b = 0x7f }, + syntax_keyword = { r = 0xc6, g = 0xa0, b = 0xf6 }, + syntax_function = { r = 0x8a, g = 0xad, b = 0xf4 }, + syntax_type = { r = 0xee, g = 0xd4, b = 0x9f }, + syntax_variable = { r = 0xca, g = 0xd3, b = 0xf5 }, + syntax_tag = { r = 0x8a, g = 0xad, b = 0xf4 }, + diff_add_bg = { r = 0x3b, g = 0x47, b = 0x4a }, + diff_remove_bg = { r = 0x48, g = 0x38, b = 0x4b }, + } }, + { name = 'Gruvbox Dark Hard', palette = { + canvas_fg = { r = 0xeb, g = 0xdb, b = 0xb2 }, + canvas_bg = { r = 0x1d, g = 0x20, b = 0x21 }, + surface = { r = 0x3c, g = 0x38, b = 0x36 }, + accent = { r = 0x83, g = 0xa5, b = 0x98 }, + muted = { r = 0x92, g = 0x83, b = 0x74 }, + success = { r = 0xb8, g = 0xbb, b = 0x26 }, + err = { r = 0xfb, g = 0x49, b = 0x34 }, + warn = { r = 0xfa, g = 0xbd, b = 0x2f }, + purple = { r = 0xd3, g = 0x86, b = 0x9b }, + secondary = { r = 0x8e, g = 0xc0, b = 0x7c }, + syntax_string = { r = 0xb8, g = 0xbb, b = 0x26 }, + syntax_number = { r = 0xd3, g = 0x86, b = 0x9b }, + syntax_keyword = { r = 0xfb, g = 0x49, b = 0x34 }, + syntax_function = { r = 0xb8, g = 0xbb, b = 0x26 }, + syntax_type = { r = 0xfa, g = 0xbd, b = 0x2f }, + syntax_variable = { r = 0xeb, g = 0xdb, b = 0xb2 }, + syntax_tag = { r = 0xfe, g = 0x80, b = 0x19 }, + diff_add_bg = { r = 0x5a, g = 0x63, b = 0x3a }, + diff_remove_bg = { r = 0x79, g = 0x23, b = 0x29 }, + } }, + { name = 'Gruvbox Dark Soft', palette = { + canvas_fg = { r = 0xeb, g = 0xdb, b = 0xb2 }, + canvas_bg = { r = 0x32, g = 0x30, b = 0x2f }, + surface = { r = 0x3c, g = 0x38, b = 0x36 }, + accent = { r = 0x83, g = 0xa5, b = 0x98 }, + muted = { r = 0x92, g = 0x83, b = 0x74 }, + success = { r = 0xb8, g = 0xbb, b = 0x26 }, + err = { r = 0xfb, g = 0x49, b = 0x34 }, + warn = { r = 0xfa, g = 0xbd, b = 0x2f }, + purple = { r = 0xd3, g = 0x86, b = 0x9b }, + secondary = { r = 0x8e, g = 0xc0, b = 0x7c }, + syntax_string = { r = 0xb8, g = 0xbb, b = 0x26 }, + syntax_number = { r = 0xd3, g = 0x86, b = 0x9b }, + syntax_keyword = { r = 0xfb, g = 0x49, b = 0x34 }, + syntax_function = { r = 0xb8, g = 0xbb, b = 0x26 }, + syntax_type = { r = 0xfa, g = 0xbd, b = 0x2f }, + syntax_variable = { r = 0xeb, g = 0xdb, b = 0xb2 }, + syntax_tag = { r = 0xfe, g = 0x80, b = 0x19 }, + diff_add_bg = { r = 0x68, g = 0x6d, b = 0x43 }, + diff_remove_bg = { r = 0x7b, g = 0x2c, b = 0x2f }, + } }, + { name = 'Gruvbox Light', palette = { + canvas_fg = { r = 0x3c, g = 0x38, b = 0x36 }, + canvas_bg = { r = 0xfb, g = 0xf1, b = 0xc7 }, + surface = { r = 0xeb, g = 0xdb, b = 0xb2 }, + accent = { r = 0x07, g = 0x66, b = 0x78 }, + muted = { r = 0x92, g = 0x83, b = 0x74 }, + success = { r = 0x79, g = 0x74, b = 0x0e }, + err = { r = 0x9d, g = 0x00, b = 0x06 }, + warn = { r = 0xb5, g = 0x76, b = 0x14 }, + purple = { r = 0x8f, g = 0x3f, b = 0x71 }, + secondary = { r = 0x42, g = 0x7b, b = 0x58 }, + syntax_string = { r = 0x79, g = 0x74, b = 0x0e }, + syntax_number = { r = 0x8f, g = 0x3f, b = 0x71 }, + syntax_keyword = { r = 0x9d, g = 0x00, b = 0x06 }, + syntax_function = { r = 0x79, g = 0x74, b = 0x0e }, + syntax_type = { r = 0xb5, g = 0x76, b = 0x14 }, + syntax_variable = { r = 0x3c, g = 0x38, b = 0x36 }, + syntax_tag = { r = 0xaf, g = 0x3a, b = 0x03 }, + diff_add_bg = { r = 0xd5, g = 0xd3, b = 0x9b }, + diff_remove_bg = { r = 0xfc, g = 0x94, b = 0x87 }, + } }, + { name = 'Gruvbox Light Hard', palette = { + canvas_fg = { r = 0x3c, g = 0x38, b = 0x36 }, + canvas_bg = { r = 0xf9, g = 0xf5, b = 0xd7 }, + surface = { r = 0xeb, g = 0xdb, b = 0xb2 }, + accent = { r = 0x07, g = 0x66, b = 0x78 }, + muted = { r = 0x92, g = 0x83, b = 0x74 }, + success = { r = 0x79, g = 0x74, b = 0x0e }, + err = { r = 0x9d, g = 0x00, b = 0x06 }, + warn = { r = 0xb5, g = 0x76, b = 0x14 }, + purple = { r = 0x8f, g = 0x3f, b = 0x71 }, + secondary = { r = 0x42, g = 0x7b, b = 0x58 }, + syntax_string = { r = 0x79, g = 0x74, b = 0x0e }, + syntax_number = { r = 0x8f, g = 0x3f, b = 0x71 }, + syntax_keyword = { r = 0x9d, g = 0x00, b = 0x06 }, + syntax_function = { r = 0x79, g = 0x74, b = 0x0e }, + syntax_type = { r = 0xb5, g = 0x76, b = 0x14 }, + syntax_variable = { r = 0x3c, g = 0x38, b = 0x36 }, + syntax_tag = { r = 0xaf, g = 0x3a, b = 0x03 }, + diff_add_bg = { r = 0xd3, g = 0xd6, b = 0xa5 }, + diff_remove_bg = { r = 0xfc, g = 0x96, b = 0x90 }, + } }, + { name = 'Gruvbox Light Soft', palette = { + canvas_fg = { r = 0x3c, g = 0x38, b = 0x36 }, + canvas_bg = { r = 0xf2, g = 0xe5, b = 0xbc }, + surface = { r = 0xeb, g = 0xdb, b = 0xb2 }, + accent = { r = 0x07, g = 0x66, b = 0x78 }, + muted = { r = 0x92, g = 0x83, b = 0x74 }, + success = { r = 0x79, g = 0x74, b = 0x0e }, + err = { r = 0x9d, g = 0x00, b = 0x06 }, + warn = { r = 0xb5, g = 0x76, b = 0x14 }, + purple = { r = 0x8f, g = 0x3f, b = 0x71 }, + secondary = { r = 0x42, g = 0x7b, b = 0x58 }, + syntax_string = { r = 0x79, g = 0x74, b = 0x0e }, + syntax_number = { r = 0x8f, g = 0x3f, b = 0x71 }, + syntax_keyword = { r = 0x9d, g = 0x00, b = 0x06 }, + syntax_function = { r = 0x79, g = 0x74, b = 0x0e }, + syntax_type = { r = 0xb5, g = 0x76, b = 0x14 }, + syntax_variable = { r = 0x3c, g = 0x38, b = 0x36 }, + syntax_tag = { r = 0xaf, g = 0x3a, b = 0x03 }, + diff_add_bg = { r = 0xce, g = 0xcb, b = 0x94 }, + diff_remove_bg = { r = 0xf7, g = 0x8b, b = 0x7f }, + } }, + { name = 'Dracula Soft', palette = { + canvas_fg = { r = 0xf6, g = 0xf6, b = 0xf5 }, + canvas_bg = { r = 0x29, g = 0x2a, b = 0x35 }, + surface = { r = 0x21, g = 0x22, b = 0x2c }, + accent = { r = 0xa7, g = 0xdf, b = 0xef }, + muted = { r = 0x70, g = 0x74, b = 0x7f }, + success = { r = 0x87, g = 0xe5, b = 0x8e }, + err = { r = 0xdd, g = 0x6e, b = 0x6b }, + warn = { r = 0xe8, g = 0xed, b = 0xa2 }, + purple = { r = 0xba, g = 0xa0, b = 0xe8 }, + secondary = { r = 0xe4, g = 0x8c, b = 0xc1 }, + syntax_string = { r = 0xe8, g = 0xed, b = 0xa2 }, + syntax_number = { r = 0xba, g = 0xa0, b = 0xe8 }, + syntax_keyword = { r = 0xe4, g = 0x8c, b = 0xc1 }, + syntax_function = { r = 0x87, g = 0xe5, b = 0x8e }, + syntax_type = { r = 0xbc, g = 0xf4, b = 0xf5 }, + syntax_variable = { r = 0xf6, g = 0xf6, b = 0xf5 }, + syntax_tag = { r = 0xa7, g = 0xdf, b = 0xef }, + } }, + { name = 'Kanagawa Wave', palette = { + canvas_fg = { r = 0xdc, g = 0xd7, b = 0xba }, + canvas_bg = { r = 0x1f, g = 0x1f, b = 0x28 }, + surface = { r = 0x16, g = 0x16, b = 0x1d }, + accent = { r = 0x7e, g = 0x9c, b = 0xd8 }, + muted = { r = 0x72, g = 0x71, b = 0x69 }, + success = { r = 0x98, g = 0xbb, b = 0x6c }, + err = { r = 0xe8, g = 0x24, b = 0x24 }, + warn = { r = 0xff, g = 0x9e, b = 0x3b }, + purple = { r = 0x95, g = 0x7f, b = 0xb8 }, + secondary = { r = 0x7a, g = 0xa8, b = 0x9f }, + syntax_string = { r = 0x98, g = 0xbb, b = 0x6c }, + syntax_number = { r = 0xd2, g = 0x7e, b = 0x99 }, + syntax_keyword = { r = 0x95, g = 0x7f, b = 0xb8 }, + syntax_function = { r = 0x7e, g = 0x9c, b = 0xd8 }, + syntax_type = { r = 0x7a, g = 0xa8, b = 0x9f }, + syntax_variable = { r = 0xdc, g = 0xd7, b = 0xba }, + syntax_tag = { r = 0x7f, g = 0xb4, b = 0xca }, + diff_add_bg = { r = 0x2b, g = 0x33, b = 0x28 }, + diff_remove_bg = { r = 0x43, g = 0x24, b = 0x2b }, + } }, + { name = 'Kanagawa Dragon', palette = { + canvas_fg = { r = 0xc5, g = 0xc9, b = 0xc5 }, + canvas_bg = { r = 0x18, g = 0x16, b = 0x16 }, + surface = { r = 0x0d, g = 0x0c, b = 0x0c }, + accent = { r = 0x8b, g = 0xa4, b = 0xb0 }, + muted = { r = 0x73, g = 0x7c, b = 0x73 }, + success = { r = 0x98, g = 0xbb, b = 0x6c }, + err = { r = 0xe8, g = 0x24, b = 0x24 }, + warn = { r = 0xff, g = 0x9e, b = 0x3b }, + purple = { r = 0x89, g = 0x92, b = 0xa7 }, + secondary = { r = 0x8e, g = 0xa4, b = 0xa2 }, + syntax_string = { r = 0x8a, g = 0x9a, b = 0x7b }, + syntax_number = { r = 0xa2, g = 0x92, b = 0xa3 }, + syntax_keyword = { r = 0x89, g = 0x92, b = 0xa7 }, + syntax_function = { r = 0x8b, g = 0xa4, b = 0xb0 }, + syntax_type = { r = 0x8e, g = 0xa4, b = 0xa2 }, + syntax_variable = { r = 0xc5, g = 0xc9, b = 0xc5 }, + syntax_tag = { r = 0x94, g = 0x9f, b = 0xb5 }, + diff_add_bg = { r = 0x2b, g = 0x33, b = 0x28 }, + diff_remove_bg = { r = 0x43, g = 0x24, b = 0x2b }, + } }, + { name = 'Kanagawa Lotus', palette = { + canvas_fg = { r = 0x54, g = 0x54, b = 0x64 }, + canvas_bg = { r = 0xf2, g = 0xec, b = 0xbc }, + surface = { r = 0xd5, g = 0xce, b = 0xa3 }, + accent = { r = 0x4d, g = 0x69, b = 0x9b }, + muted = { r = 0x8a, g = 0x89, b = 0x80 }, + success = { r = 0x6f, g = 0x89, b = 0x4e }, + err = { r = 0xe8, g = 0x24, b = 0x24 }, + warn = { r = 0xe9, g = 0x8a, b = 0x00 }, + purple = { r = 0x62, g = 0x4c, b = 0x83 }, + secondary = { r = 0x59, g = 0x7b, b = 0x75 }, + syntax_string = { r = 0x6f, g = 0x89, b = 0x4e }, + syntax_number = { r = 0xb3, g = 0x5b, b = 0x79 }, + syntax_keyword = { r = 0x62, g = 0x4c, b = 0x83 }, + syntax_function = { r = 0x4d, g = 0x69, b = 0x9b }, + syntax_type = { r = 0x59, g = 0x7b, b = 0x75 }, + syntax_variable = { r = 0x54, g = 0x54, b = 0x64 }, + syntax_tag = { r = 0x66, g = 0x93, b = 0xbf }, + diff_add_bg = { r = 0xb7, g = 0xd0, b = 0xae }, + diff_remove_bg = { r = 0xd9, g = 0xa5, b = 0x94 }, + } }, +} + +local function blend(base, accent, percent) + local q = 100 - percent + return { + r = math.floor((base.r * q + accent.r * percent) / 100), + g = math.floor((base.g * q + accent.g * percent) / 100), + b = math.floor((base.b * q + accent.b * percent) / 100), + } +end + +local function fg(color) + return string.format("\27[38;2;%d;%d;%dm", color.r, color.g, color.b) +end + +local function bg(color) + return string.format("\27[48;2;%d;%d;%dm", color.r, color.g, color.b) +end + +local function derive(p) + local values = { + canvas_fg = fg(p.canvas_fg), + canvas_bg = bg(p.canvas_bg), + dim = fg(p.muted), + assistant = fg(p.canvas_fg), + user = fg(p.canvas_fg), + tool = fg(p.accent), + footer = fg(p.muted), + tool_text = fg(p.canvas_fg), + tool_pending = fg(p.muted), + tool_success = fg(p.success), + tool_error = fg(p.err), + compaction_header = fg(p.warn), + thinking_header = fg(p.purple), + cursor = "\27[7m", + err = fg(p.err), + welcome = fg(p.accent), + waiting_peak = fg(p.canvas_fg), + waiting_near = fg(p.secondary), + waiting_far = fg(p.muted), + err_diff = fg(p.err), + add_diff = fg(p.success), + thinking = fg(p.muted), + compaction = fg(p.muted), + + user_bg = bg(p.surface), + tool_pending_bg = bg(p.surface), + tool_success_bg = bg(blend(p.canvas_bg, p.success, 20)), + tool_error_bg = bg(blend(p.canvas_bg, p.err, 20)), + diff_remove_bg = bg(p.diff_remove_bg or blend(p.canvas_bg, p.err, 20)), + diff_add_bg = bg(p.diff_add_bg or blend(p.canvas_bg, p.success, 20)), + user_text = fg(p.canvas_fg), + tool_header = fg(p.accent), + + syntax_base = fg(p.canvas_fg), + syntax_comment = fg(p.muted), + syntax_string = fg(p.syntax_string), + syntax_number = fg(p.syntax_number), + syntax_keyword = fg(p.syntax_keyword), + syntax_function = fg(p.syntax_function), + syntax_type = fg(p.syntax_type), + syntax_variable = fg(p.syntax_variable), + syntax_tag = fg(p.syntax_tag), + + reset = "\27[0m", + } + return values +end + +local M = {} + +function M.activate() + local panto = require("panto") + for _, item in ipairs(palettes) do + local exists = pcall(panto.ext.style, item.name) + if not exists then + panto.ext.style(item.name, derive(item.palette)) + end + end +end + +function M.values(name) + for _, item in ipairs(palettes) do + if item.name == name then + return derive(item.palette) + end + end +end + +return { name = "themes.popular", activate = M.activate, values = M.values } diff --git a/scripts/verify-against-core.lua b/scripts/verify-against-core.lua new file mode 100644 index 0000000..f66bb74 --- /dev/null +++ b/scripts/verify-against-core.lua @@ -0,0 +1,50 @@ +-- Run this with the real Panto interpreter from pantograph: +-- panto lua scripts/verify-against-core.lua +-- +-- Compare the extension's computed snapshots directly with core so mismatches +-- remain visible even when activation skips names already owned by core. + +local source = debug.getinfo(1, "S").source +local scripts_dir = source:match("^@(.*)/[^/]+$") or "." +local root = scripts_dir .. "/.." +package.path = root .. "/?.lua;" .. package.path + +local panto = require("panto") +local roles = { + "dim", "assistant", "user", "tool", "footer", "tool_text", + "tool_pending", "tool_success", "tool_error", "compaction_header", + "thinking_header", "cursor", "err", "welcome", "waiting_peak", + "waiting_near", "waiting_far", "err_diff", "add_diff", "thinking", + "compaction", "user_bg", "tool_pending_bg", "tool_success_bg", + "tool_error_bg", "diff_remove_bg", "diff_add_bg", "user_text", + "tool_header", "canvas_fg", "canvas_bg", "syntax_base", + "syntax_comment", "syntax_string", "syntax_number", "syntax_keyword", + "syntax_function", "syntax_type", "syntax_variable", "syntax_tag", + "reset", +} +local moved = { + "Tokyo Night", "Catppuccin Mocha", "Gruvbox Dark", "Solarized Light", + "Solarized Dark", "Nord", "Dracula", "Tokyo Storm", "Tokyo Moon", + "Tokyo Day", "Catppuccin Latte", "Catppuccin Frappe", + "Catppuccin Macchiato", "Gruvbox Dark Hard", "Gruvbox Dark Soft", + "Gruvbox Light", "Gruvbox Light Hard", "Gruvbox Light Soft", + "Dracula Soft", +} +local entry = require("panto-popular-themes.init") +assert(entry.name == "themes.popular", "wrong extension entry") +assert(type(entry.values) == "function", "missing extension values") + +-- Activation skips names already owned by core or another extension, so +-- compare the generated snapshots directly instead of relying on a conflict. +for _, name in ipairs(moved) do + local expected = panto.ext.style(name) + local actual = entry.values(name) + assert(actual, "extension has no theme " .. name) + for _, role in ipairs(roles) do + if expected[role] ~= actual[role] then + error("theme " .. name .. " role " .. role .. " mismatch", 0) + end + end +end + +entry.activate() |
