@@ -503,11 +503,10 @@ internal Task LoadHostProfilesAsync(CancellationToken cancellationToken)
503503
504504 private Task EnableShellIntegrationAsync ( CancellationToken cancellationToken )
505505 {
506- // Imported on 11/17/22 from
506+ // Imported on 01/03/23 from
507507 // https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1
508508 // with quotes escaped, `__VSCodeOriginalPSConsoleHostReadLine` removed (as it's done
509509 // in our own ReadLine function), and `[Console]::Write` replaced with `Write-Host`.
510- // TODO: We can probably clean some of this up.
511510 const string shellIntegrationScript = @"
512511# Prevent installing more than once per session
513512if (Test-Path variable:global:__VSCodeOriginalPrompt) {
@@ -523,8 +522,21 @@ private Task EnableShellIntegrationAsync(CancellationToken cancellationToken)
523522
524523$Global:__LastHistoryId = -1
525524
525+ function Global:__VSCode-Escape-Value([string]$value) {
526+ # NOTE: In PowerShell v6.1+, this can be written `$value -replace '…', { … }` instead of `[regex]::Replace`.
527+ # Replace any non-alphanumeric characters.
528+ [regex]::Replace($value, '[\\\n;]', { param($match)
529+ # Encode the (ascii) matches as `\x<hex>`
530+ -Join (
531+ [System.Text.Encoding]::UTF8.GetBytes($match.Value) | ForEach-Object { '\x{0:x2}' -f $_ }
532+ )
533+ })
534+ }
526535
527536function Global:Prompt() {
537+ # NOTE: We disable strict mode for the scope of this function because it unhelpfully throws an
538+ # error when $LastHistoryEntry is null, and is not otherwise useful.
539+ Set-StrictMode -Off
528540 $FakeCode = [int]!$global:?
529541 $LastHistoryEntry = Get-History -Count 1
530542 # Skip finishing the command if the first command has not yet started
@@ -545,7 +557,7 @@ private Task EnableShellIntegrationAsync(CancellationToken cancellationToken)
545557 } else {
546558 $CommandLine = """"
547559 }
548- $Result += $CommandLine.Replace(""\"", ""\\"").Replace(""`n"", ""\x0a"").Replace("";"", ""\x3b"" )
560+ $Result += $(__VSCode-Escape-Value $CommandLine )
549561 $Result += ""`a""
550562 # Command finished exit code
551563 # OSC 633 ; D [; <ExitCode>] ST
@@ -557,9 +569,11 @@ private Task EnableShellIntegrationAsync(CancellationToken cancellationToken)
557569 $Result += ""$([char]0x1b)]633;A`a""
558570 # Current working directory
559571 # OSC 633 ; <Property>=<Value> ST
560- $Result += if($pwd.Provider.Name -eq 'FileSystem'){""$([char]0x1b)]633;P;Cwd=$($pwd.ProviderPath)`a""}
572+ $Result += if($pwd.Provider.Name -eq 'FileSystem'){""$([char]0x1b)]633;P;Cwd=$(__VSCode-Escape-Value $pwd.ProviderPath)`a""}
561573 # Before running the original prompt, put $? back to what it was:
562- if ($FakeCode -ne 0) { Write-Error ""failure"" -ea ignore }
574+ if ($FakeCode -ne 0) {
575+ Write-Error ""failure"" -ea ignore
576+ }
563577 # Run the original prompt
564578 $Result += $Global:__VSCodeOriginalPrompt.Invoke()
565579 # Write command started
@@ -579,12 +593,14 @@ function Set-MappedKeyHandler {
579593 Set-PSReadLineKeyHandler -Chord $Sequence -Function $Handler.Function
580594 }
581595}
596+
582597function Set-MappedKeyHandlers {
583598 Set-MappedKeyHandler -Chord Ctrl+Spacebar -Sequence 'F12,a'
584599 Set-MappedKeyHandler -Chord Alt+Spacebar -Sequence 'F12,b'
585600 Set-MappedKeyHandler -Chord Shift+Enter -Sequence 'F12,c'
586601 Set-MappedKeyHandler -Chord Shift+End -Sequence 'F12,d'
587602}
603+
588604Set-MappedKeyHandlers
589605 " ;
590606
0 commit comments