Skip to content

Context-Aware tmux Status Line #32

@rjernst

Description

@rjernst

branch: tmux-claude-status

Spec: Context-Aware tmux Status Line

Overview

Make the tmux status bar and starship prompt context-aware:

  1. When the active tmux pane is running claude, show a second (top) status line with the working directory in powerline style (using ~ for $HOME). The path should not appear in the normal (bottom) status line.
  2. When the active pane is a normal shell, display a single status line with no path (starship prompt already shows it).
  3. Hide the starship [time] module when running inside tmux (the tmux status bar already shows the clock).

Architecture

scripts/tmux-claude-status    # Helper script called from tmux status format
tmux/themes/powerline-base16.tmuxtheme  # Theme updates (remove path, wire helper)
starship/starship.toml        # Conditional time module

The helper script is called via #() in the tmux status format on every status-interval tick. It checks #{pane_current_command}, and as a side effect toggles status 2 / status on and sets status-format[0] for the path line. This handles both pane-focus switching and in-pane command changes (e.g., starting claude from zsh).


1. tmux Claude Detection

The helper script must:

  • Check the focused pane's current command via tmux display-message -p '#{pane_current_command}'.
  • If the command is claude:
    • Set status 2 (two status lines).
    • Set status-format[0] to a powerline-styled line showing the working directory. Use ~ shorthand for $HOME. Match the color palette of the existing theme (ANSI colours 0–7).
    • The path line should be styled with powerline arrows consistent with the existing left/right status segments.
  • If the command is anything else:
    • Set status on (single status line).
  • The script should be idempotent — avoid unnecessary tmux set calls if the status is already in the desired state (check current value first to prevent flicker).

2. tmux Theme Changes

In tmux/themes/powerline-base16.tmuxtheme:

  • Remove the path (#{pane_current_path}) from status-right. The path will either be in the dedicated top line (claude) or in the starship prompt (normal shell).
  • Keep the clock in status-right.
  • Add a #() call to the helper script so it runs on each status refresh. This can be embedded in status-right or status-left — the script's stdout can be empty since its purpose is the side effect.

3. Starship Time Module

In starship/starship.toml:

  • Disable the built-in [time] module (disabled = true).
  • Add a [custom.time] module that:
    • Runs date "+%H:%M:%S" (matching the existing time format).
    • Uses when = '[ -z "$TMUX" ]' so it only appears outside tmux.
    • Preserves the existing visual style: [\ue0b6](fg:240)[ at $output ](bg:240 dimmed white)[\ue0b4](fg:240).
    • Uses shell = ['sh'].
  • Update the format string to replace $time with ${custom.time}.

Implementation Plan

Step 1: Create tmux status helper script [done]

Files:

  • scripts/tmux-claude-status — New helper script

Implement:

  1. Create scripts/tmux-claude-status as a POSIX shell script.
  2. Get the current pane command: tmux display-message -p '#{pane_current_command}'.
  3. Get the current pane path: tmux display-message -p '#{pane_current_path}'.
  4. Replace $HOME prefix with ~ in the path.
  5. If command is claude:
    • Check current status option value. If not already 2, set status 2.
    • Build a powerline-styled format string for the path using the theme's ANSI color palette.
    • Set status-format[0] to the path format string (only if changed, to avoid flicker).
  6. If command is not claude:
    • If status is not on, set status on.
  7. Script should output nothing (empty stdout) — it operates entirely via side effects.
  8. Make the script executable.

Test:

  • Run shellcheck scripts/tmux-claude-status — no warnings.
  • Run the script manually in a tmux session and verify it toggles status lines.

Verify: shellcheck scripts/tmux-claude-status passes clean.

Review: Check for correctness of tmux option queries, idempotency, and POSIX compliance.

Address feedback: Fix all review findings. Re-run checks.

Step 2: Update tmux theme [done]

Files:

  • tmux/themes/powerline-base16.tmuxtheme — Modify status-right, add helper call

Implement:

  1. Remove the path segment (#(echo #{pane_current_path} | sed ...)) from status-right.
  2. Keep the clock segment in status-right.
  3. Add #(tmux-claude-status) to the status format (e.g., at the end of status-right or status-left) so the helper runs on every refresh tick. Since the script outputs nothing, it won't affect the visible status text.

Test:

  • Source the theme in a tmux session: tmux source-file tmux/themes/powerline-base16.tmuxtheme.
  • Verify: single status line with no path in a normal shell pane.
  • Open a pane running claude and verify: two status lines appear, top line shows styled path.
  • Switch back to a normal pane and verify: reverts to single status line.

Verify: tmux source-file tmux/themes/powerline-base16.tmuxtheme loads without errors.

Review: Check that the status bar looks correct in both modes, powerline arrows render properly.

Address feedback: Fix all review findings.

Step 3: Update starship config [done]

Files:

  • starship/starship.toml — Conditional time module

Implement:

  1. Set disabled = true on the existing [time] module.
  2. Add a [custom.time] module:
    [custom.time]
    command = 'date "+%H:%M:%S"'
    when = '[ -z "$TMUX" ]'
    format = "[\\ue0b6](fg:240)[ at $output ](bg:240 dimmed white)[\\ue0b4](fg:240)"
    shell = ['sh']
  3. In the top-level format string, replace $time with ${custom.time}.

Test:

  • Outside tmux: starship prompt shows the time segment.
  • Inside tmux: starship prompt does not show the time segment.

Verify: starship config loads without errors. Visual inspection in both contexts.

Review: Verify the powerline styling matches the original time module appearance.

Address feedback: Fix all review findings.

Notes:

  • Used single \ue0b6/\ue0b4 escapes (not double-escaped \\u) to match the convention used by all other modules in the file (e.g., [custom.java]). TOML basic strings interpret \uXXXX as unicode escapes, which is the desired behavior.

Step 4: Run all checks

Implement:

  1. Run shellcheck scripts/tmux-claude-status.
  2. Run tmux source-file tmux/themes/powerline-base16.tmuxtheme in a tmux session to verify no parse errors.
  3. Run any existing test suites: bats tests/test_*.bats (if relevant tests exist).
  4. Fix any failures and commit the fixes.

Verify: All checks pass clean.


Conventions

  • Language: POSIX sh for the helper script (runs frequently, should be fast)
  • Tests: Manual verification in tmux (shellcheck for static analysis)
  • Error messages: Silent operation — the helper script should never produce visible output or errors
  • Exit codes: Always exit 0 (status bar helper must not cause tmux errors)

Metadata

Metadata

Assignees

No one assigned

    Labels

    specRalph spec for automated executionstatus:doneCompleted

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions