From 9a330499de2184616209cb282555bceed401a81a Mon Sep 17 00:00:00 2001 From: Bill Date: Mon, 14 Sep 2026 19:27:20 +0800 Subject: [PATCH] fix: track bare drive switches (d:) for cwd memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PowerShell/cmd users hop drives with a bare 'd:' — no cd keyword — so the typed-command tracker never saw it, the pane's cwd stayed at its creation directory, and the session snapshot restored it to home. Treat a bare drive-letter line as a cd to the drive root; the main-process existence check drops it on platforms without drive letters. --- src/renderer/src/terminal/cwdTracker.ts | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/renderer/src/terminal/cwdTracker.ts b/src/renderer/src/terminal/cwdTracker.ts index 4f9d111..119dffc 100644 --- a/src/renderer/src/terminal/cwdTracker.ts +++ b/src/renderer/src/terminal/cwdTracker.ts @@ -4,8 +4,9 @@ * Two signals feed the same store: * 1. the shell itself, over OSC 7 (`file://host/path`) or ConEmu's OSC 9;9 — * exact, but only present when shell integration is on; - * 2. the command the user typed, matched against the `cd` family — the - * fallback that works with no shell cooperation at all. + * 2. the command the user typed, matched against the `cd` family plus the + * bare drive switch (`d:`) of cmd.exe / PowerShell — the fallback that + * works with no shell cooperation at all. * * Both are platform-neutral: path resolution and existence checks happen in the * main process (`src/main/cwd.ts`) where node's `path` lives, so nothing here @@ -21,14 +22,26 @@ */ const CD_COMMAND = /^\s*(?:cd|chdir|sl|set-location|pushd|push-location)(?:\s+([\s\S]*))?$/i +/** + * Bare drive switch (`d:`, `D:`) — cmd.exe and PowerShell change the current + * drive with no `cd` keyword at all, and it is the common way to land on + * another drive on Windows. Treated as a cd to the drive root; the main + * process's existence check quietly drops it on platforms where drive + * letters mean nothing (POSIX resolves it to a nonexistent relative path). + */ +const DRIVE_SWITCH = /^\s*([a-zA-Z]):\s*$/ + /** * Return the argument of a cd-style command line, or null when the line is not - * one. An empty string means "bare cd" (the shell's home directory). + * one. An empty string means "bare cd" (the shell's home directory). A bare + * drive switch yields the drive root (`D:\`). */ export function cdArgument(line: string): string | null { const match = line.match(CD_COMMAND) - if (!match) return null - return (match[1] ?? '').trim() + if (match) return (match[1] ?? '').trim() + const drive = line.match(DRIVE_SWITCH) + if (drive) return `${drive[1].toUpperCase()}:\\` + return null } /** Payload of an OSC 9 sequence that follows the ConEmu `9;` convention. */