Skip to content

feat(app): derive dynamic tab title from foreground process and cwd#22

Merged
simota merged 1 commit into
mainfrom
feat/dynamic-tab-title
Jul 17, 2026
Merged

feat(app): derive dynamic tab title from foreground process and cwd#22
simota merged 1 commit into
mainfrom
feat/dynamic-tab-title

Conversation

@simota

@simota simota commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

The tab/window title never changed from its initial state unless the shell explicitly set one. When there is no OSC 0/2 title and no user rename, the title now falls back to a live label built from the focused pane's foreground process and OSC 7 cwd tail (cargo — noa); a plain interactive shell collapses to just the cwd tail, and with no information it stays "Noa". User renames and explicit OSC titles keep their existing priority, and the format mirrors the sidebar card naming via the shared cwd_tail helper.

Changes

  • resolved_tab_title now takes (override, shell_title, cwd, process) and owns the fallback chain; new dynamic_tab_title / is_plain_shell helpers in geometry.rs
  • Render path feeds the focused pane's term.cwd (already under the terminal lock) and the session-store process name into the title resolution
  • SessionDelta::Process application requests a window redraw so process changes update the title even with the sidebar closed (cwd/OSC-title changes already ride the io thread's Redraw)
  • cwd_tail promoted to pub(crate) and shared with the sidebar to avoid duplication

Test plan

  • cargo test -p noa-app --offline → 950 passed, 0 failed (new unit tests: cwd-only / process-only / both / plain-shell collapse incl. -zsh and /bin/bash / no info → "Noa" / OSC title wins / override wins)
  • cargo clippy --workspace --offline clean (no new warnings), cargo fmt --check clean
  • Manual: run cargo run -p noa, start vim — title reads vim — <dir>; cd updates the tail; OSC 2 and tab rename still take priority

When the shell has not set an OSC 0/2 title (and the user has not
renamed the tab), fall back to a live title built from the focused
pane's foreground process and OSC 7 cwd tail (`cargo — noa`), matching
the sidebar card naming via the shared cwd_tail helper. A plain
interactive shell collapses to just the cwd tail; with no information
the title stays "Noa". User overrides and explicit OSC titles keep
their existing priority.

Foreground-process changes now request a window redraw when the
session delta is applied so the title tracks them even with the
sidebar closed; cwd and OSC title changes already ride the io
thread's Redraw path.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9299927804

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +100 to +107
let focused_process = self
.windows
.get(&window_id)
.map(|state| state.focused_pane)
.and_then(|pane_id| {
self.session_store
.get(&Self::session_card_id(window_id, pane_id))
.and_then(|card| card.process.clone())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep process title independent of session cards

When a pane has not produced any PTY output yet, such as noa -e sleep 60 or another silent explicit command, no SessionDelta::Upsert has created a SessionCard; SessionStore::apply drops SessionDelta::Process updates for missing cards, and the process poller will not resend the same name. Because the new fallback reads the foreground process only through self.session_store.get(...), the title remains Noa/cwd instead of showing the foreground process until output occurs or the process changes. Store the latest process independently of the card, or let process deltas create/update the card before relying on it for the title.

Useful? React with 👍 / 👎.

@simota
simota merged commit e59407d into main Jul 17, 2026
1 check passed
@simota
simota deleted the feat/dynamic-tab-title branch July 17, 2026 05:23
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.

1 participant