tmux: circled window numbers via an async hook, not a per-redraw conditional
The old format nested ten #{?#{==:#{window_index},N},...} conditionals inside
window-status-format, so tmux re-evaluated all ten for every window on every
redraw -- and redraws follow PANE ACTIVITY, not status-interval. A busy pane
ran them several times a second.
tmux-window-icons stamps each window with its symbol as a window-level user
option, so the format is a plain #{?#{@icon},#{@icon},#{window_index}} lookup.
It runs from run-shell -b on window-change hooks only, never on the render path.
Deliberately NOT a #() job: those expand EMPTY while restarting, which is the
bug that made status elements wink out in the first place. Reading a pre-set
option means a slow or failed run leaves the previous icon in place instead of
blanking the field.
Hooks are limited to those tmux 3.7b actually has -- after-kill-window,
after-move-window and after-swap-window do not exist and error on source.
window-unlinked covers kills; session-window-changed catches move/swap, which
have no hook of their own.
This commit is contained in:
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Stamp every window with its circled-number icon as a WINDOW-level user option.
|
||||
#
|
||||
# Why not do this in the format string: the obvious approach nests ten
|
||||
# #{?#{==:#{window_index},N},...} conditionals, which tmux re-evaluates for
|
||||
# every window on every redraw -- and redraws are driven by PANE ACTIVITY, so a
|
||||
# busy pane re-runs all ten per window, several times a second.
|
||||
#
|
||||
# Here the work happens ONCE per window change (driven by hooks) and the render
|
||||
# path becomes #{@icon}: a plain variable lookup, no conditionals, no forks.
|
||||
#
|
||||
# Do NOT call this from the status format itself -- that would make it a #()
|
||||
# job, which renders EMPTY while restarting and is the original bug.
|
||||
symbols=(❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾ ❿)
|
||||
while IFS= read -r w; do
|
||||
idx=${w##*:}
|
||||
[[ $idx =~ ^[0-9]+$ ]] || continue
|
||||
if (( idx >= 1 && idx <= ${#symbols[@]} )); then
|
||||
icon=${symbols[idx-1]}
|
||||
else
|
||||
icon=$idx
|
||||
fi
|
||||
tmux set -w -t "$w" @icon "$icon" 2>/dev/null
|
||||
done < <(tmux list-windows -a -F '#{session_name}:#{window_index}' 2>/dev/null)
|
||||
Reference in New Issue
Block a user