Repository navigation
feat(tui-theme): write the TUI theme file for every theme and signal its readers - #24
Merged
Merged
Conversation
The syntax and tree-sitter highlight groups were Lua text inside neovim.py, so a second generator wanting the same styles could only copy them, and the copies would drift. They now live in lib/neovim_highlights.py as Python data, with the semantic colors palette.lua maps them through, and neovim.py writes the same Lua from it. Every theme's generated colorscheme is byte-identical. The table sits in lib/ because every script in lib/generators/ is read as a generator. Importing it from there writes __pycache__/, now ignored. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9b4-580a-78e4-993a-0b0cbf56760f Worklog: 2555.1
…its readers Terminal programs on gotermstyle draw in the 16 ANSI colors, which hold no shade near the background, so a selected row can only be reversed into a slab. gotermstyle's tuitheme reads a theme file of colors and styles keyed by role. This writes that file for every theme, installs it where the reader looks, and asks each running reader to reread it on apply. tui-theme.py writes tui-theme.json. ui comes from theme.yml with its fallbacks resolved: the selection is special.selection_fg on extended.ui_selection or special.selection_bg, and the accent is extended.ui_accent or base0D. markdown and syntax resolve the shared Neovim highlight table, so a note or snippet in a terminal program wears the styles it has in Neovim. Every key the format names is written. apply_tui_theme installs it as ~/.config/tui-theme/<id>.json with current.json linking to it, the path tuitheme reads with none given. The directory holds only theme files, so the themes sit beside the link. reload_tui_theme sends SIGUSR2 to each reader by name. Off Linux it first checks the binary on PATH carries Go's build-info marker, because the Go runtime ignores an unrequested SIGUSR2 and another program may die of it. reload_apps maps a hyphen in an app's name to its reload function's underscore. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9b4-580a-78e4-993a-0b0cbf56760f Worklog: 2555.1
…s relative gotermstyle's reader ignores a relative XDG_CONFIG_HOME, as the XDG spec asks, and falls back to ~/.config. The install used it raw, so the two named different files and every reader stayed on its built-in colors. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9cf-f0a1-76ce-a000-cdf27a041ee5 Worklog: 2555.1
…es name tui-theme.py types the schema's ui, markdown and base syntax keys out again, and nothing held the copy level. A role the reader's schema gains and the generator misses would draw in the 16-color default in every theme with both suites green. The test fetches the schema at each file's $schema URL, and skips when it cannot reach it. Agent-Name: claude-code-unattended Agent-Session: 4773265d-bd77-424c-b9db-836de857b797 Agent-Run: 01a1b9cf-f0a1-76ce-a000-cdf27a041ee5 Worklog: 2555.1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Terminal programs built on gotermstyle draw in the 16 ANSI colors, which hold no shade near the background. So a selected row can only be marked by reversing it, which on a dark theme is a bright slab of the foreground color. gotermstyle's
tuithemepackage reads a theme file of colors and styles keyed by role. This writes that file for every theme, installs it where the reader looks, and signals each running reader to reread it ontheme apply.Written by Claude Code session 4773265d-bd77-424c-b9db-836de857b797.
What to look at
5d25ede—lib/neovim_highlights.pyholds the syntax and tree-sitter groups that were Lua text inneovim.py, plus the semantic colorspalette.luamaps them through. Check thatlua_specandlua_groupsinneovim.pyreproduce the old text.lib/generate-all.sh --generators neovimleaves every theme's colorscheme unchanged.lib/generators/tui-theme.py—ui_groupis eachuirole's fallback chain.group_stylefollows alinkand turnsundercurlintounderline.syntax_groupskips a capture whose link leaves the shared table, which today is only@string.special.pathlinkingDirectory. The reader falls back along the dots for it.lib/lib.sh—apply_tui_themeputs each theme besidecurrent.jsonin~/.config/tui-theme/rather than in athemes/subdirectory, becauseinstall_themed_artifactlinks within one directory. It ignores a relativeXDG_CONFIG_HOME, as gotermstyle's reader does, so the two always name one file.reload_tui_themesignalsTUI_THEME_READERSby name._signal_reloadnow passes the name to its off-Linux check, which_go_binary_on_pathneeds.reload_appscallsreload_${app//-/_}, so the app namedtui-themereachesreload_tui_theme.How it was verified
bats tests/passes. The new tests arethe TUI theme lands at the path gotermstyle reads with none givenandevery TUI theme writes the roles its schema declares.$schemaURL, and skips until that URL resolves. With a stubcurlserving gotermstyle's branch schema, it passes. It fails when the schema alone gainsui.cursoror a basesyntaxrole.XDG_CONFIG_HOME=rel,apply_tui_themelinks~/.config/tui-theme/current.jsonand creates norel/directory.lib/generate-all.sh --generators neovimran 20 jobs with 0 failed, andgit statusshowed no theme file changed.themes/*/tui-theme.jsonvalidate withcheck-jsonschemaagainst gotermstyle'stuitheme/schema/v1.json.apply_tui_theme charcoal-emberalone installed~/.config/tui-theme/charcoal-ember.jsonwithcurrent.jsonlinking to it. A scratch Go program on gotermstyle's branch paintedui.selectionas\x1b[0;38;2;197;200;198;48;2;55;59;65m. Thenapply_tui_theme kanagawaand_signal_reload tuitheme-demo _go_binary_on_pathran, and the same running program painted\x1b[0;38;2;200;192;147;48;2;45;79;103mwith no restart. The link was set back to charcoal-ember.grep -qa 'Go buildinf:'matched two of the readers' binaries andgofumpt, and did not matchls,bashorbtop.What changes
tui-theme.json, andtheme currentlists it astui-theme.theme applyinstalls it on every platform, as~/.config/tui-theme/<id>.jsonwith~/.config/tui-theme/current.jsonlinking to the applied one.theme applysends SIGUSR2 to each running process named inTUI_THEME_READERS. On Linux only a process whose SigCgt mask catches SIGUSR2 gets it, as for btop. Elsewhere only a name whose binary on PATH is a Go binary gets it.tuithemecatches the signal and ignores it, so nothing visible happens until a reader adopts the package.$schemaURL resolves once gotermstyle'stuithemelands on its main branch. The file works without it, and an editor's validation waits for it.Decisions, and what they rejected
ui.matchis a foreground color,extended.ui_matchfalling back tobase0A. A filter match drawn as a foreground still reads on the selected row.ui.mutedfalls back tobase04, the colorneovim.pyalready uses forfg_dim. Only 4 of the 20 themes setextended.fg_dim.ui.panelis written as{"bg": …}, because a bare color in the format is a foreground.syntax.parameterandsyntax.punctuationread@variable.parameterand@punctuation.delimiter. Neovim has no bare@parameteror@punctuation.reload_tui_themepassingtrueas the off-Linux check. On macOS a non-Go process sharing a reader's name would die of the SIGUSR2 it does not catch.What this does not do
current.jsonis gotermstyle's default path. A reader'sTUI_THEME_FILEpoints it at another file instead.