Skip to content

fix(tmux): one status process per tick instead of a Node job per placeholder per window - #1096

Merged
will-jack-and-jilll merged 1 commit into
mainfrom
fix/1095-tmux-one-process-per-tick
Oct 16, 2026
Merged

will-jack-and-jilll merged 1 commit into
mainfrom
fix/1095-tmux-one-process-per-tick

Conversation

@gugu91

@gugu91 gugu91 commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Fixes #1095.

What changes

Placeholders no longer start a process each. They expand to plain option reads (#{@pi_window_state}, @pi_window_name, @pi_window_unread, @pi_window_count, @pi_window_summary, @pi_session_summary). One hidden job, #(#{@pi_query} env publish), is appended to status-right when any placeholder is in use. Each tick it:

  1. reads every pane, window and session in one tmux call,
  2. runs one ps liveness check,
  3. writes only the changed aggregates in one chained set-option call. An unchanged tick writes nothing, so nothing redraws.

The job lives in status-right on purpose. tmux keys #() jobs by window inside the window list, but by client outside it.

  • Placeholder names and behaviour are unchanged. Counts still render 0 in windows without Pi, so #{?#{pi_count},…} keeps working.
  • Formats expanded by an older version of the plugin are rewritten to the new reads when the plugin loads again.
  • Uninstall removes the job from status-right.
  • The publisher still writes only pane data. The aggregates belong to the companion.
  • status.ts SOCKET publish is new. The per-target query modes are unchanged.

Evidence

Measured on a live tmux server with an attached client and status-interval 1, counting job runs over 6 s with 4 windows:

Formats Job runs in 6 s
Old (one job per placeholder per window) 29
New 6 (one per tick, flat as windows grow)

Before the fix, on my laptop with 10 windows, 3 placeholders and status-interval 5, the status bar used about 0.65 of a core and showed up to 15 Node processes at once.

Tests

  • plugin.test.ts (updated, isolated tmux):
    • expanded window formats contain no #(
    • status-right gets exactly one publisher job, and reloading is idempotent
    • uninstall removes the job
    • legacy expansions are upgraded
    • counts render 0 before the first publish
    • the job prints nothing
    • each window and session gets its own aggregate
    • a released pane clears its window and session
  • Running the session aggregate test caught a real bug while I wrote this: set-option -s targets the server, not the session.
  • pnpm test in tmux/: 31 passed, plus the publisher node --test. tsc --noEmit, oxlint and lint:agent-standards are clean.

…eholder per window

Placeholders now read window/session options written by a single hidden
publisher job in status-right. tmux keys jobs by window inside the window
list but by client outside it, so the job runs once per client per tick.
Legacy expansions are rewritten on reload; uninstall removes the job.

Fixes #1095
@will-jack-and-jilll
will-jack-and-jilll merged commit 0482583 into main Oct 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tmux: one process per tick instead of a Node job per placeholder per window

2 participants