diff options
| author | JJ Liebig <jonathan.liebig@gmail.com> | 2026-08-17 22:29:47 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-17 23:29:47 +0300 |
| commit | 19022d03c902de586009b1d156bc20b01ce48135 (patch) | |
| tree | b299bf56e5f3ab02cb900ada10ac3735661a3e05 /src | |
| parent | 94093acb0aaefd7136108d402e25f3bdb86bde73 (diff) | |
fix: sync powershell process working directory (#2879)
Diffstat (limited to 'src')
| -rw-r--r-- | src/pane.rs | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/pane.rs b/src/pane.rs index a47e62eb..0b3edf7d 100644 --- a/src/pane.rs +++ b/src/pane.rs @@ -1474,8 +1474,8 @@ fn resolve_shell_for_login_mode(shell: &str) -> io::Result<String> { /// wraps whatever `prompt` function the user's profile left behind so each /// prompt render appends the cwd as OSC 9;9 — the sequence Windows Terminal /// and ConEmu standardized for shell integration. PowerShell never updates -/// its Win32 process cwd on `Set-Location`, so prompt-time reporting is the -/// only reliable cwd source on Windows. +/// its Win32 process cwd on `Set-Location`, so the prompt hook updates it when +/// possible before reporting the cwd. /// /// The snippet must not contain double quotes: powershell.exe parses its /// command line with its own rules that disagree with the ArgvQuote escaping @@ -1487,7 +1487,7 @@ fn resolve_shell_for_login_mode(shell: &str) -> io::Result<String> { /// The original prompt must be invoked before any other statement in the /// wrapper: anything that runs first resets `$?`, so a status-aware user /// prompt would show success after a failed command (verified on 5.1). -pub(crate) const WINDOWS_POWERSHELL_SHELL_INTEGRATION_COMMAND: &str = r"if ($null -eq $global:__HerdrOriginalPrompt) { $global:__HerdrOriginalPrompt = $function:prompt; function global:prompt { $out = @(& $global:__HerdrOriginalPrompt) -join ' '; $loc = $ExecutionContext.SessionState.Path.CurrentLocation; if ($loc.Provider.Name -eq 'FileSystem') { $esc = [string][char]27; $out += $esc + ']9;9;' + $loc.ProviderPath + $esc + '\' }; $out } }"; +pub(crate) const WINDOWS_POWERSHELL_SHELL_INTEGRATION_COMMAND: &str = r"if ($null -eq $global:__HerdrOriginalPrompt) { $global:__HerdrOriginalPrompt = $function:prompt; function global:prompt { $out = @(& $global:__HerdrOriginalPrompt) -join ' '; $loc = $ExecutionContext.SessionState.Path.CurrentLocation; if ($loc.Provider.Name -eq 'FileSystem') { try { [Environment]::CurrentDirectory = $loc.ProviderPath } catch {}; $esc = [string][char]27; $out += $esc + ']9;9;' + $loc.ProviderPath + $esc + '\' }; $out } }"; fn pane_shell_command_builder_for_target( shell_config: PaneShellConfig<'_>, @@ -3350,7 +3350,11 @@ mod tests { } let script = WINDOWS_POWERSHELL_SHELL_INTEGRATION_COMMAND; - assert!(script.contains("]9;9;"), "missing OSC 9;9 emit: {script}"); + let cwd_sync = script + .find("[Environment]::CurrentDirectory = $loc.ProviderPath") + .expect("wrapper must synchronize the Win32 process cwd"); + let osc_report = script.find("]9;9;").expect("wrapper must emit OSC 9;9"); + assert!(cwd_sync < osc_report, "cwd sync must precede OSC report"); assert!( script.contains("$global:__HerdrOriginalPrompt = $function:prompt"), "must wrap the profile-defined prompt: {script}" |
