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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions