Skip to content

here mode level 1: match teamocil — use set_environment + respawn-pane, keep send_keys cd only #1031

@tony

Description

@tony

Parent: #1030

Approach

Match teamocil's --here strategy: minimize send_keys to only the unavoidable cd command. Use tmux primitives for everything else.

Changes to builder.py:678-727

1. Environment: replace send_keys("export ...") with session.set_environment()

tmuxp already uses session.set_environment() for session-level env vars at builder.py:557-559. Window-level env vars set on the session are inherited by all new panes.

# Before (lines 708-715): send_keys for each env var
for _ekey, _eval in environment.items():
    _here_pane.send_keys(f"export {_ekey}={shlex.quote(str(_eval))}", enter=True)

# After: use tmux session environment (inherited by panes)
if environment:
    for _ekey, _eval in environment.items():
        session.set_environment(_ekey, str(_eval))

This matches how teamocil handles it — teamocil does not inject env vars at all. The session environment is the tmux-native mechanism.

Caveat: set_environment only affects new shells spawned in the session. The already-running shell in the reused pane won't see them. This is acceptable because:

  • Subsequent panes (created via split) will inherit them
  • The reused pane can pick them up if the user starts a new shell
  • This is the same limitation teamocil has (it doesn't set env vars at all in --here)

2. Shell replacement: replace send_keys(window_shell) with respawn-pane

# Before (lines 724-727): send_keys to type shell command
_here_pane.send_keys(window_shell, enter=True)

# After: use respawn-pane to restart pane with new shell
if window_shell:
    _here_pane = window.active_pane
    if _here_pane is not None:
        _here_pane.cmd("respawn-pane", "-k", window_shell)

respawn-pane -k kills the current process and starts a new one in the same pane. Available since tmux 1.6, well within tmuxp's 3.2+ minimum. This also picks up the session environment set above.

3. Directory: keep send_keys("cd ...") (same as teamocil)

# Keep as-is (lines 695-701) — matches teamocil
active_pane.send_keys(f"cd {shlex.quote(start_directory)}", enter=True)

teamocil uses the same approach: send_keys cd "/path" for the reused window's first pane.

Result

Category Before After
cd send_keys send_keys (same as teamocil)
Environment send_keys export (N calls) session.set_environment() (tmux primitive)
Shell replacement send_keys (types into pane) respawn-pane -k (tmux primitive)

send_keys surface reduced from 3 categories to 1, matching teamocil exactly.

Risk assessment

  • Low risk: session.set_environment() is already used in the same file
  • Low risk: respawn-pane is a stable tmux command (available since 1.6)
  • Caveat: env vars only visible to new shells, not the existing one — acceptable trade-off
  • Remaining: send_keys cd still assumes a shell prompt (same as teamocil)

Tests to add/update

  • Update test_here_mode_provisions_environment to verify session.show_environment() instead of pane output
  • Add test for window_shell via respawn-pane
  • Keep existing test_here_mode_start_directory_special_chars (still uses send_keys cd)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions