Files
drunkendotfiles/.tmux.conf.user
T

77 lines
4.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ---------------------------------------------------------------------------
# Statusline element-flicker fix (2026-08-19).
# Sourced at the end of ~/.yadr/.tmux.conf, so these override what it sets.
# Kept HERE so a yadr re-bootstrap cannot clobber it.
#
# SYMPTOM dissimulo reported: "the statusbar is having a seizure -- elements
# appear and disappear at random." NOT the whole bar blanking (a 30fps screen
# recording of the bar showed zero frame-to-frame variation, and a whole-desktop
# capture showed nothing changing near it). Individual ELEMENTS winking out.
#
# CAUSE: `#(...)` in a status format is a tmux JOB. While that job is being
# (re)started its expansion is EMPTY, so the element vanishes until it finishes.
# tmux re-runs those jobs whenever the status is redrawn and the job is not
# already running -- and status redraws are driven by PANE ACTIVITY, not by
# `status-interval`. With a busy TUI in the pane (a `claude` session) the jobs
# were being restarted several times a second, so the username and the IP
# flickered in and out constantly. Measured: `#(whoami)` and `#(tmux-net)`
# expanded EMPTY in 30 out of 30 consecutive renders.
#
# FIX: resolve both into tmux USER OPTIONS and reference those. `#{@user}` and
# `#{@net}` are plain variable lookups -- no job, so nothing can ever be
# half-started and render empty. Rendered text is byte-identical to before.
# @user - a username cannot change within a session: read it ONCE.
# @net - the IP CAN change, so refresh on a slow background loop
# (4 forks/minute instead of several a second). The loop exits by
# itself when tmux goes away, because `tmux set` then fails.
#
# Bonus, already measured: this also cut the tmux server from ~25% of a core to
# ~12% and eliminated the fork churn (17 execs/10s -> 0).
#
# DO NOT "simplify" #{@user}/#{@net} back to #(whoami)/#(~/.local/bin/tmux-net).
# That is the bug, not a tidier way of writing it.
# ---------------------------------------------------------------------------
run-shell 'tmux set -g @user "$(whoami)"'
run-shell 'tmux set -g @net "$($HOME/.local/bin/tmux-net)"'
run-shell -b 'while sleep 60; do tmux set -g @net "$($HOME/.local/bin/tmux-net)" 2>/dev/null || exit 0; done'
# These lengths are measured against the RAW format string, NOT the rendered
# width: tmux applies them as #{T;=/N:status-right}, truncating BEFORE the
# #[...] style directives are stripped. status-right renders ~46 columns but is
# ~129 characters of source. A cap below the raw length severs the string
# mid-way, which looks exactly like 'the right side of the bar disappeared'.
# Set here as well as in .tmux.conf so this file stays self-sufficient.
set -g status-left-length 451
set -g status-right-length 451
set -g status-left '#[fg=colour235,bg=colour252,bold] ❐ #S #[fg=colour252,bg=colour238,nobold]#[fg=colour245,bg=colour238,bold] #{@user} '
# The trailing %S is drawn in bg-on-bg (colour234 on colour234) so it is
# INVISIBLE, but it makes the status string CHANGE every second.
#
# WHY THAT MATTERS -- the second half of the bug: tmux only repaints the status
# line when its computed content DIFFERS from what it last drew. With the clock
# at minute resolution and @user/@net static, the string was byte-identical for
# up to 60s at a stretch; so when anything wiped the bar it STAYED wiped until
# the minute rolled over. That is the "sometimes the entire bar disappears" half.
# A once-per-second change forces a repaint, so a wipe self-heals within ~1s.
# It costs one redraw of one row and NO forks (that is only affordable because
# the #() jobs above became #{@user}/#{@net}).
set -g status-right '#[bold][#[nobold,fg=colour229]#h#[fg=default] / #[fg=colour229]#{@net}#[fg=default,bold]]#[nobold,fg=colour255] %-I:%M%P %d-%b-%Y #[fg=colour39]★ Stardate %Y.%j#[fg=colour255] '
# ---- circled window numbers, stamped asynchronously ----------------------
# The icon is computed ONCE per window change and stored as a window-level
# user option; the format below is a plain #{@icon} lookup. The old version
# nested ten #{?#{==:#{window_index},N},...} conditionals evaluated for every
# window on every redraw, and redraws follow PANE ACTIVITY, not status-interval.
# run-shell -b is backgrounded, so none of this sits on the render path.
set -g window-status-format '#[fg=colour235,bg=colour252,nobold] #{?#{@icon},#{@icon},#{window_index}} #{b:pane_current_path} #W '
set -g window-status-current-format '#[fg=colour234,bg=colour39,bold] [#[fg=colour232,bold]#{?window_zoomed_flag,#[fg=colour228],} #{?#{@icon},#{@icon},#{window_index}} #{b:pane_current_path} #W #[fg=colour234,bold]] '
run-shell -b '$HOME/.local/bin/tmux-window-icons'
set-hook -g after-new-window 'run-shell -b "$HOME/.local/bin/tmux-window-icons"'
set-hook -g window-linked 'run-shell -b "$HOME/.local/bin/tmux-window-icons"'
set-hook -g window-unlinked 'run-shell -b "$HOME/.local/bin/tmux-window-icons"'
set-hook -g session-window-changed 'run-shell -b "$HOME/.local/bin/tmux-window-icons"'