Skip to content

feat: name the Ghostty tab after the branch - #44

Open
johnpangalos wants to merge 1 commit into
mainfrom
feat/tab-titles
Open

feat: name the Ghostty tab after the branch#44
johnpangalos wants to merge 1 commit into
mainfrom
feat/tab-titles

Conversation

@johnpangalos

Copy link
Copy Markdown
Owner

What

wt switch / wt root now name the new tab/window after the branch, on by default. Set WT_NO_TITLE to opt out.

Why it's done this way

Ghostty's AppleScript surface configuration has no settable title — the name property on window/tab/terminal is read-only in the scripting dictionary, and the surface configuration record only exposes cwd, command, initial input, wait-after-command, and env vars. So we can't set the title through the same AppleScript path wt uses.

Instead we set it the way any program does: wrap the surface command so it emits an OSC 2 ; <branch> BEL sequence before exec-ing the editor:

```
/bin/bash -c 'printf "\033]2;branch\007"; exec /path/to/nvim'
```

This composes cleanly with the two existing quirks:

  • Ghostty already runs the surface command as bash -c "exec <cmd>", so the outer exec hands straight off to our wrapper — no lingering shell, and wait after command semantics are preserved (the editor is still the final process).
  • The \033/\007 survive AppleScript's asString escaping because printf (not AppleScript) interprets them.

Caveat

The title only sticks for programs that don't set their own. Editors like Neovim ('title' off by default) leave it alone, so it reads as the branch name. A shell with a prompt title hook (e.g. Ghostty shell integration) will overwrite it. This is documented in the README note and the wrapCmdWithTitle docstring.

Title value

Branch name, falling back to the worktree's directory basename for a detached/bare checkout.

Tests

  • wrapCmdWithTitle is tested by actually running the wrapper through bash exactly as Ghostty does and asserting the real OSC-2 bytes emitted — covering the full quoting pipeline, shell metacharacters/quotes in titles, and control-character stripping.
  • CLI tests cover the default-on wrapping and the WT_NO_TITLE opt-out.
  • Full suite (76) + tsc --noEmit green.

🤖 Generated with Claude Code

Ghostty's AppleScript surface configuration has no settable title, so
`wt` now sets it the way any program does: it wraps the surface command
to emit an `OSC 2 ; <branch> BEL` sequence, then execs the editor.
Ghostty already runs the surface command as `bash -c "exec <cmd>"`, so
the outer exec hands straight off to this wrapper with no lingering shell.

The title is the branch name (or the worktree dir basename for a
detached/bare checkout). It sticks for programs that leave the title
alone (most editors); a shell with a prompt title hook overwrites it.
On by default; set WT_NO_TITLE to opt out.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@johnpangalos
johnpangalos marked this pull request as ready for review July 7, 2026 07:20
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