Skip to content

API additions for tmuxinator/teamocil parity#636

Open
tony wants to merge 14 commits intomasterfrom
parity
Open

API additions for tmuxinator/teamocil parity#636
tony wants to merge 14 commits intomasterfrom
parity

Conversation

@tony
Copy link
Member

@tony tony commented Mar 7, 2026

Summary

Three non-breaking API additions to support tmuxp's feature parity with tmuxinator (3.3.7) and teamocil (1.4.2).

Closes #635. Tracking: tmux-python/tmuxp#1016

  • Pre-execution command logging: tmux_cmd now logs the command before execution via logger.debug, enabling future dry-run mode in tmuxp (tmuxinator's debug / teamocil's --debug)
  • Pane.set_title(): Wraps select-pane -T and enables pane_title format variable. Uncomments pane_title in formats.py, adds field to neo.Obj, adds Pane.set_title() method and Pane.title property alias
  • Configurable tmux binary path: Server(tmux_bin="/path/to/tmux") threads through Server.cmd(), Server.raise_if_dead(), and neo.fetch_objs(). Supports wemux, byobu, or custom-built tmux binaries (tmuxinator's tmux_command equivalent)

All changes are fully backward-compatible — new parameters default to existing behavior.

Test plan

  • All 884 existing tests pass
  • New tests for pre-execution logging (test_tmux_cmd_pre_execution_logging)
  • New tests for set_title with plain text and special characters
  • New tests for tmux_bin default, custom path, and invalid path
  • Doctests pass for Pane.set_title() and Pane.title
  • mypy clean, ruff clean

tony added a commit that referenced this pull request Mar 7, 2026
why: Document the three new features for the upcoming release.
what:
- Pane.set_title() and pane_title support
- Configurable tmux binary path (Server tmux_bin parameter)
- Pre-execution command logging in tmux_cmd
@codecov
Copy link

codecov bot commented Mar 7, 2026

Codecov Report

❌ Patch coverage is 65.62500% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 45.68%. Comparing base (95644de) to head (79d399c).

Files with missing lines Patch % Lines
src/libtmux/pane.py 44.44% 4 Missing and 1 partial ⚠️
src/libtmux/server.py 70.00% 2 Missing and 1 partial ⚠️
src/libtmux/common.py 81.81% 2 Missing ⚠️
src/libtmux/neo.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #636      +/-   ##
==========================================
+ Coverage   45.48%   45.68%   +0.19%     
==========================================
  Files          22       22              
  Lines        2260     2281      +21     
  Branches      361      363       +2     
==========================================
+ Hits         1028     1042      +14     
- Misses       1085     1092       +7     
  Partials      147      147              

☔ View full report in Codecov by Sentry.
📢 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 a commit that referenced this pull request Mar 7, 2026
why: Document the three new features for the upcoming release.
what:
- Pane.set_title() and pane_title support
- Configurable tmux binary path (Server tmux_bin parameter)
- Pre-execution command logging in tmux_cmd
tony added 14 commits March 7, 2026 05:36
why: tmux_cmd logs stdout after execution and exceptions, but never logs
the command before execution. Pre-execution logging is the prerequisite
for a future dry-run mode in tmuxp (tmuxinator's debug / teamocil's
--debug equivalent).
what:
- Add logger.debug call before subprocess.Popen in tmux_cmd.__init__
- Add test verifying pre-execution log message contains command
why: tmux supports select-pane -T and #{pane_title} (since 2.6).
tmuxinator uses this for named panes. libtmux had no wrapper and
pane_title was commented out of formats.py.
what:
- Uncomment pane_title in formats.py PANE_FORMATS list
- Add pane_title field to neo.Obj dataclass
- Add Pane.set_title() method using select-pane -T
- Add Pane.title property alias for pane_title
- Add tests for set_title with plain and special characters
why: shutil.which("tmux") is hardcoded in tmux_cmd and Server. No way
to use wemux, byobu, or a custom-built tmux. tmuxinator supports
tmux_command config key including wemux module.
what:
- Add tmux_bin keyword arg to tmux_cmd.__init__ (backward compatible)
- Add tmux_bin parameter to Server.__init__ with pathlib.Path support
- Thread tmux_bin through Server.cmd(), Server.raise_if_dead(), and
  neo.fetch_objs()
- Session/Window/Pane inherit via server.cmd() delegation
- Add tests for default, custom path, and invalid path scenarios
why: Document the three new features for the upcoming release.
what:
- Pane.set_title() and pane_title support
- Configurable tmux binary path (Server tmux_bin parameter)
- Pre-execution command logging in tmux_cmd
…l server param

why: server parameter is typed as Server (non-optional), so the
`server is not None` guard is dead code that obscures intent.
what:
- Simplify tmux_bin assignment to direct attribute access
why: Conform to CLAUDE.md logging standards — structured extra enables
assertion on record attributes instead of fragile string matching.
what:
- Add import shlex to common.py
- Replace subprocess.list2cmdline with shlex.join (POSIX quoting)
- Add extra={"tmux_cmd": ...} to pre-execution debug log
- Update test to assert on caplog.records attributes
…id tmux_bin

why: Invalid custom tmux_bin raised raw FileNotFoundError from subprocess
instead of the domain-specific TmuxCommandNotFound, creating an
inconsistent API surface.
what:
- Catch FileNotFoundError before generic Exception in tmux_cmd.__init__
- Re-raise as TmuxCommandNotFound from None
- Update test_tmux_bin_invalid_path to expect TmuxCommandNotFound
…d execution

why: Previous test only checked attribute storage, not that the custom
binary actually appears in executed commands.
what:
- Add caplog fixture to capture debug logs
- Assert custom tmux_bin path appears in structured log records
why: Docstring claimed "spaces and unicode" coverage but only tested ASCII.
what:
- Add unicode character (π) test case to test_set_title_special_characters
…valid tmux_bin

why: subprocess.check_call raises FileNotFoundError when tmux_bin points to
a nonexistent path, leaking a raw exception instead of TmuxCommandNotFound.
what:
- Wrap subprocess.check_call in try/except FileNotFoundError
- Add test_tmux_bin_invalid_path_raise_if_dead test case
why: f-string in logger.exception and .format() in post-exec log defeat lazy
formatting; shlex.join(cmd) was computed twice redundantly.
what:
- Compute shlex.join(cmd) once into cmd_str variable
- Replace f-string in logger.exception with lazy formatting + extra
- Replace .format() post-exec log with lazy formatting + structured extra
- Guard post-exec debug log with logger.isEnabledFor(logging.DEBUG)
why: tmux_bin parameter was missing from the Server class docstring,
violating the convention that all parameters are documented.
what:
- Add tmux_bin entry to Parameters section after socket_name_factory
why: Returns section had type but no description, inconsistent with other
methods like resize_width/resize_height.
what:
- Add description text for the :class:\`Pane\` return type
why: "Defaults to" implies tmux_bin is set to shutil.which at init time,
but it actually stays None and the fallback happens at execution time.
what:
- Change "Defaults to" to "Falls back to ... at execution time"
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.

API additions for tmuxinator/teamocil parity

1 participant