From 6c9be0f1b130bc0e1515da9386256afd67bf53fe Mon Sep 17 00:00:00 2001 From: Jeffrey Leon Date: Fri, 3 Jul 2026 11:24:38 -0400 Subject: [PATCH] feat(git): default state_target to both MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A dirty work tree escalated only the icon slot (state_target auto resolved to leading), leaving a two-tone pill when the text variant displays the accent. Bake the per-module default to both — the same pattern cpu/ram use in metric_module.conf — so every accent-bearing slot warms together. The internal cascade tier is unreachable here: themux_options.conf bakes the module tier to auto, so the default must ride the user-facing option. Tests assert the stock core keeps one dirty switch (soft text has no accent channel, the renderer collapses it) and a solid text carries three (icon bg, text bg, trailing bg re-assert). --- docs/reference/configuration.md | 5 ++++- docs/reference/status-line.md | 7 ++++++- modules/git.conf | 10 ++++++++++ tests/git_module.sh | 25 +++++++++++++++++++++---- tests/git_module_expected.txt | 3 ++- themux_options.conf | 4 ++-- 6 files changed, 45 insertions(+), 9 deletions(-) diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 0c2df97..7547868 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -477,7 +477,10 @@ Invalid values behave like `auto`. For example, `session` keeps the existing prefix behavior by default while its leading is visible (red leading when `client_prefix` is active), but `@themux_session_state_target text` moves that red active accent to the text and `@themux_session_leading_show off` lets `auto` move -it there for you. +it there for you. Some modules ship their own per-module default: `git` sets +`@themux_git_state_target` to `both` so a dirty work tree warms every slot +whose variant displays the accent, and `cpu`/`ram` do the same for their live +threshold colour (see below). The `cpu`/`ram` threshold modules carry tmux-cpu's live level colour `#{_bg_color}` as their accent — green at rest, warming yellow → red as the diff --git a/docs/reference/status-line.md b/docs/reference/status-line.md index 687d337..50b929c 100644 --- a/docs/reference/status-line.md +++ b/docs/reference/status-line.md @@ -218,7 +218,12 @@ switches the accent from `@themux_git_color` to `@themux_git_active_color` through the module active state, so the pill warms natively under any variant and always agrees with the text. Divergence does not escalate: the probe checks the work tree only, so a diverged-but-clean tree keeps the resting -accent. +accent. The escalation targets both slots by default +(`@themux_git_state_target` defaults to `both`), so every slot whose variant +displays the accent warms — with a `solid` text the whole pill turns, while +the stock `soft` text has no accent channel and keeps its neutral block. Set +the target to `leading` or `text` to warm one slot only, or `off` to never +escalate — see [state target](./configuration.md#status-modules). ```sh set -g @themux_git_color "#{E:@thm_role_accent}" # resting (clean) diff --git a/modules/git.conf b/modules/git.conf index 39b1f76..07d8289 100644 --- a/modules/git.conf +++ b/modules/git.conf @@ -60,6 +60,16 @@ set -ogq "@themux_${MODULE_NAME}_active_color" "#{E:@thm_role_notice}" set -gq "@_tmx_${MODULE_NAME}_dirty" '#("#{E:@_tmx_git_script}" --dirty "#{pane_current_path}")' set -ogq "@themux_${MODULE_NAME}_active_when" "#{E:@_tmx_${MODULE_NAME}_dirty}" +# The dirty escalation targets both slots: state_target defaults to both so +# every slot whose variant displays the accent warms on a dirty tree. Under +# `auto` an accent-bearing text (solid/subtle/naked) kept the resting accent +# next to an escalated icon — a two-tone pill. The stock soft text has no +# accent channel, so there the renderer still collapses the text switch and +# nothing changes. Same per-module default pattern as cpu/ram in +# utils/metric_module.conf; @themux_git_state_target stays a user option to +# move or suppress the escalation. +set -ogq "@themux_${MODULE_NAME}_state_target" "both" + # Only render inside a git work tree (a cheap rev-parse, evaluated per refresh). set -gq "@_tmx_${MODULE_NAME}_in_repo" '#(git -C "#{pane_current_path}" rev-parse --is-inside-work-tree 2>/dev/null)' set -gq "@themux_${MODULE_NAME}_when" "#{E:@_tmx_${MODULE_NAME}_in_repo}" diff --git a/tests/git_module.sh b/tests/git_module.sh index baa2479..54e7ef2 100644 --- a/tests/git_module.sh +++ b/tests/git_module.sh @@ -33,10 +33,27 @@ tmux show -gqv @themux_git_text | { grep -oF '#("#{E:@_tmx_git_script}"' || true printf 'script_path ' tmux show -gqv @_tmx_git_script | { grep -oF 'utils/git_status.sh' || true; } -# The baked core routes the active state through the dirty probe (an expanded -# draw would need a live repo path, so assert on the raw core). -printf 'core_active_switch ' -tmux show -gqv @_tmx_module_git_core | { grep -oF '#{?#{E:@_tmx_git_dirty},' || true; } | sort -u +# The baked core routes the active state through the dirty probe. The module +# defaults state_target to `both`, but the stock text variant is `soft` +# (surface bg, plain fg — no accent channel), so the text style resolves the +# same in both states and the renderer collapses that switch: only the icon +# bg carries the conditional. An expanded draw would need a live repo path, +# so count on the raw core; grep -c would count lines and the core is a +# single line, hence grep -o | wc -l. +printf 'core_active_switch_slots ' +tmux show -gqv @_tmx_module_git_core | { grep -oF '#{?#{E:@_tmx_git_dirty},' || true; } | wc -l | tr -d ' ' + +# With a text variant that displays the accent (solid: accent bg), the both +# default routes the dirty escalation into the text slot too — the whole +# pill warms instead of the icon-only two-tone `auto` used to leave. Three +# switches: icon bg, text bg, and the trailing bg re-assert after the text +# content (the guard that keeps a self-styled text from leaking). +tmux set -g @themux_git_text_variant "solid" +src +printf 'core_active_switch_slots_solid_text ' +tmux show -gqv @_tmx_module_git_core | { grep -oF '#{?#{E:@_tmx_git_dirty},' || true; } | wc -l | tr -d ' ' +tmux set -gu @themux_git_text_variant +src # gitmux keeps its stock colours but sits on the theme's darkest step. print_option @themux_gitmux_text_bg diff --git a/tests/git_module_expected.txt b/tests/git_module_expected.txt index edf22d4..b0e11ad 100644 --- a/tests/git_module_expected.txt +++ b/tests/git_module_expected.txt @@ -11,7 +11,8 @@ in_repo_probe rev-parse --is-inside-work-tree dirty_probe #("#{E:@_tmx_git_script}" --dirty text_invocation #("#{E:@_tmx_git_script}" script_path utils/git_status.sh -core_active_switch #{?#{E:@_tmx_git_dirty}, +core_active_switch_slots 1 +core_active_switch_slots_solid_text 3 @themux_gitmux_text_bg #{E:@thm_crust} diff --git a/themux_options.conf b/themux_options.conf index 1da31ef..8628050 100644 --- a/themux_options.conf +++ b/themux_options.conf @@ -135,8 +135,8 @@ set -ogq @themux_module_leading_show "icon" # follows the visible leading slot: leading when present, text when hidden. # Stateful modules route @themux__active_color through this selector; cpu/ram # default their own target to both so threshold colour still appears on icon and -# digits. @themux__state_target overrides one module; invalid values behave -# as auto. +# digits, and git defaults to both so a dirty tree warms the whole pill. +# @themux__state_target overrides one module; invalid values behave as auto. set -ogq @themux_module_state_target "auto" # Divider inserted by "|" between modules in the lists above. Modules/window-list