Skip to content

refactor(cli/load,tests) Migrate display-message to typed wrapper#1039

Open
tony wants to merge 2 commits into
masterfrom
libtmux-v0.56-plus-api-updates
Open

refactor(cli/load,tests) Migrate display-message to typed wrapper#1039
tony wants to merge 2 commits into
masterfrom
libtmux-v0.56-plus-api-updates

Conversation

@tony

@tony tony commented May 10, 2026

Copy link
Copy Markdown
Member

Summary

  • Drop the last two cmd("display-message", "-p", ...) escape hatches in the codebase: one in production (cli/load._reattach), six in test code (the plugin-system suite).
  • Same tmux invocation under the hood, just routed through libtmux's typed Pane.display_message(cmd, get_text=True) wrapper. No behavior change.
  • Follows the libtmux 0.56.0 bump in py(deps) Bump libtmux 0.56.0 #1038 — the wrapper itself has been around since 0.55.0, but with 0.56.0 now landed there's no remaining reason to keep the cmd() escape for this particular subcommand.

Why now

PR #1038 broadened the Pane.display_message flag coverage in libtmux 0.56.0 (format_string=, verbose=, delay=, notify=, target_client=). While auditing tmuxp for spots that could move to the new typed surface, the only remaining cmd() escape in production turned out to be the post-reattach session-name echo loop in cli/load._reattach. Five of the six other usages were in tests asserting on session/window names via the same idiom — leaving them on cmd() while production migrated would split the call shape across the codebase.

The migration itself doesn't depend on a 0.56.0-only API; this is consistency cleanup that 0.56.0's broader display_message surface made an obvious moment to do.

Changes in this PR

c54893e5cli/load(refactor[_reattach]) Use Pane.display_message wrapper

Production change. Replaces:

proc = builder.session.cmd("display-message", "-p", "'#S'")
for line in proc.stdout:
    ...

with:

active_pane = builder.session.active_pane
assert active_pane is not None
lines = active_pane.display_message("'#S'", get_text=True)
for line in lines:
    ...

The narrowing assert mirrors the existing assert builder.session is not None already at the top of _reattach(). tmux's display-message without -t defaults to the session's active pane, so the underlying invocation is byte-for-byte identical.

46b52f16tests(refactor[plugin_system]) Use Pane.display_message wrapper

Migrates six test sites in tests/cli/test_cli.py::test_reattach_plugins and four test_plugin_system_* checks in tests/workspace/test_builder.py to the same typed wrapper. Hoists active_pane once in the multi-query test that asserts on both '#S' and '#W' (replaces two separate cmd() roundtrips with two calls on the same pane reference).

Test plan

  • uv run ruff check . --fix --show-fixes clean before each commit
  • uv run ruff format . clean before each commit
  • uv run mypy clean before each commit (the narrowing assert was load-bearing — without it, Pane | None typing rejects the call)
  • uv run py.test --reruns 0 -vvv — 797 passed, 2 skipped, before each commit
  • just build-docs succeeds before each commit
  • No remaining cmd("display-message", ...) calls anywhere in src/ or tests/ (verified via grep -rn 'cmd("display-message"' src/ tests/)
@codecov

codecov Bot commented May 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.00%. Comparing base (6edda37) to head (c1ed962).
��️ Report is 89 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1039      +/-   ##
==========================================
+ Coverage   81.98%   82.00%   +0.01%     
==========================================
  Files          28       28              
  Lines        2548     2550       +2     
  Branches      485      485              
==========================================
+ Hits         2089     2091       +2     
  Misses        328      328              
  Partials      131      131              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
tony added 2 commits June 6, 2026 07:51
why: The reattach loop reached for libtmux's `Server.cmd()` escape
hatch to invoke `tmux display-message -p '#S'` for the session
name, even though libtmux has exposed a typed
`Pane.display_message()` wrapper for this exact subcommand for
several releases. With libtmux 0.56.0 now in the dependency tree
(it broadens `display_message`'s flag coverage on top of the
existing get_text path), there's no remaining reason to keep this
particular cmd() escape.

what:
- Replace `builder.session.cmd("display-message", "-p", "'#S'")`
  in `_reattach()` with
  `active_pane.display_message("'#S'", get_text=True)` against
  `builder.session.active_pane`. Same tmux invocation under the
  hood; typed call site instead of stringly-typed positional args.
- Add a narrowing assert on `active_pane` (returns `Pane | None`
  in libtmux's typing) so mypy can prove the call site is
  well-typed. Mirrors the existing `assert builder.session is not
  None` pattern at the top of `_reattach()`.
- Iterate the returned `list[str]` directly. Previously the loop
  consumed `proc.stdout` (a list), so the iteration shape is
  identical and the per-line `tmuxp_echo` / `logger.debug` body
  is unchanged.

No behavior change: the active pane is what tmux's display-message
defaults to anyway when no `-t` is passed, so the underlying tmux
invocation is byte-for-byte identical.
why: Six tests in the plugin-system suite were querying tmux for
session/window names via the same `session.cmd("display-message",
"-p", "'#S'")` escape hatch that production just migrated away
from in `cli/load.py:_reattach`. Keeping the tests on the typed
wrapper that production now uses keeps the call shape consistent
across the codebase and removes the last `cmd("display-message",
...)` site from the repo.

what:
- `tests/cli/test_cli.py::test_reattach_plugins`: replace the
  `cmd()` call with `active_pane.display_message("'#S'",
  get_text=True)` so the post-reattach assertion uses the typed
  wrapper.
- `tests/workspace/test_builder.py`: migrate four
  `test_plugin_system_*` checks (`before_workspace_builder`,
  `on_window_create`, `after_window_finished`, and the
  multi-window variant covering both `before_script` and
  `after_window_finished`) onto `active_pane.display_message()`.
  The multi-window variant hoists the active_pane lookup once and
  reuses it for both the `'#S'` and `'#W'` queries.
- Each call site adds a narrowing assert on `active_pane`
  (libtmux types it as `Pane | None`) so mypy can prove the call
  is well-typed. Mirrors the production assert added in
  `_reattach()`.

No behavior change: tmux's `display-message` defaults to the
session's active pane when no `-t` is passed, so the underlying
tmux invocations are byte-for-byte identical to the prior
`session.cmd(...)` calls.
@tony tony force-pushed the libtmux-v0.56-plus-api-updates branch from 46b52f1 to c1ed962 Compare June 6, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant