Skip to content

Open new terminals in the focused session's directory - #250

Merged
jiweiyuan merged 1 commit into
mainfrom
fix/new-terminal-cwd
Aug 12, 2026
Merged

Open new terminals in the focused session's directory#250
jiweiyuan merged 1 commit into
mainfrom
fix/new-terminal-cwd

Conversation

@jiweiyuan

@jiweiyuan jiweiyuan commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

New Terminal always started a shell at $HOME, so the shortcut people reach for to "open another shell right here" threw away where they were.

⌘T now opens the terminal in the focused session's working directory and lands it beside that session — same project, same worktree bucket — instead of creating a project-less scratch session. The directory is the cwd the session last reported over OSC 7 (workingDirectory(for:)); when no shell integration ever reported one, or the reported path isn't a local directory (an SSH terminal reports a remote path), it falls back to the session's own spawn anchor, then to the project root, and finally to $HOME when nothing is focused at all.

The seeded directory rides on a new Session.spawnDirectory, persisted so a relaunched shell reopens where it was opened. A loose terminal's own lastWorkingDirectory still wins over it — a shell that reported its cwd knows better than the seed.

A shell never lands in the Chats funnel: ⌘T from a scratch chat opens the terminal in the Terminals section, seeded with the chat's directory.

The old behavior stays available as its own verb, New Terminal at Home, in the File menu and in the sidebar's + pull-down.

Which entry points follow the focus

The + pull-down is context-free by construction — New Chat always lands in the Chats funnel, New SSH Connection always in Terminals, none of them read the selection — and it sits in the sidebar's toolbar, where "here" has no clear meaning. So its terminal entry is the $HOME one, named for where it starts. The directory-following New Terminal is reached where the terminal is actually in front of you: ⌘T, the File menu, and the Command Palette (which lists it with its ⌘T binding, alongside its other selection-dependent verbs). The Terminals section header keeps its own local "New Terminal", which adds to that container as before.

How this compares to the neighbours

  • cmux (also ghostty-based) already inherits the focused tab's directory on ⌘T; the live complaint in cmux#177 is that inheritance can't be turned off. Their root cause is worth knowing: with nothing to pass, they hand nil to ghostty_surface_new, which falls back to the process CWD — / for a Finder-launched app. This ladder never ends in nil, which is the same trap Project.firstRunProjects() already documents.
  • Ghostty defaults window-inherit-working-directory to true, needs shell integration for it, and falls back to a configured default otherwise — the same three rungs.
  • Zed anchors its terminal to the project (terminal.working_directory, default current_project_directory) and never follows a cd. That is the editor answer; termio is terminal-first, and the report behind New Terminal starts in $HOME, not the focused session's directory #243 was a user expecting terminal semantics.

On the second binding

The issue proposed ⌘⇧T for New Terminal at Home. It ships unbound instead, for the reason splitLeft / splitUp already ship unbound: opening a shell at ~ when your work is in a project is the rare direction, and ⌘⇧T is "reopen closed tab" muscle memory everywhere else on the Mac — worth keeping free for a session-shaped command later. The verb stays in the File menu and in Settings ▸ Keyboard, so it is one binding away for anyone who wants it. Reverting is one line in KeyCommandCatalog.

Worth noting that ghostty and cmux both spell this escape hatch as a config key rather than a verb, and cmux#177 is what that costs when the key isn't plumbed through: five confused users and an open bug. A menu item calling addScratchTerminal() — a function that already had three call sites — can't fail that way.

Known limit

For a session in a real project, right after an app relaunch and before the shell's first OSC 7, ⌘T lands at the project root rather than the subdirectory the shell was in. That is deliberate: a project session's anchor is the project (docs/design/loose-terminal-entity.md), and only loose terminals persist their own cwd. It can never land at ~. cmux has the same gap without the floor — after a restore, its ⌘T drops to ~ (last comment on #177).

Docs

web/landing/src/data/keybindings.json is regenerated with pnpm keybindings:sync; the shortcut tables are not hand-written. The one prose paragraph added to keyboard.mdx is translated in keyboard.zh-CN.mdx and re-stamped. docs:check passes.

Verification

  • swift build, swift test (172 tests), and pnpm docs:check pass. CI is green.
  • Not verified at runtime. The dev channel is held by another session, so the File menu items, ⌘T from a project session, and the spawned shell's actual cwd have not been exercised in a running app. Before merging, this is worth one manual pass: cd inside a project session then ⌘T (new terminal starts there, row lands beside it), ⌘T from a loose terminal (sibling in Terminals at the same cwd), File ▸ New Terminal at Home (starts at ~, no shortcut shown), and Settings ▸ Keyboard listing it under File as unbound.

Closes #243

Release Notes:

  • New Terminal (⌘T) now opens in the current session's working directory, beside that session. File ▸ New Terminal at Home still starts a shell at your home directory.

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
landing Ready Ready Preview Aug 12, 2026 9:46am

Request Review

New Terminal (⌘T) starts the shell where the user already is — the cwd the
focused session last reported over OSC 7, falling back to that session's own
spawn anchor and then $HOME — and lands the row beside that session, in its
project and worktree bucket. ⌘⇧T keeps the always-$HOME terminal as its own
File menu verb.

Closes #243
@jiweiyuan
jiweiyuan force-pushed the fix/new-terminal-cwd branch from e756aa4 to 744e627 Compare August 12, 2026 09:46
@jiweiyuan
jiweiyuan merged commit 3287c67 into main Aug 12, 2026
4 checks passed
@jiweiyuan
jiweiyuan deleted the fix/new-terminal-cwd branch August 12, 2026 09:50
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.

New Terminal starts in $HOME, not the focused session's directory

1 participant