PowerShell / PSReadLine

A bash inspired readline implementation for PowerShell
BSD 2-Clause "Simplified" License
3.71k stars 294 forks source link

Unexpected backslash with OSC 9;9 prompt #3719

Open yan12125 opened 1 year ago

yan12125 commented 1 year ago

Prerequisites

Steps to reproduce

  1. Configure OSC 9;9 for PowerShell and add custom prompt in $PROFILE following https://learn.microsoft.com/en-us/windows/terminal/tutorials/new-tab-same-directory#powershell-powershellexe-or-pwshexe:

    function prompt {
    $loc = $executionContext.SessionState.Path.CurrentLocation;
    
    $out = "PS $loc$('>' * ($nestedPromptLevel + 1)) ";
    if ($loc.Provider.Name -eq "FileSystem") {
    $out += "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\"
    }
    return $out
    }
  2. Type a single quote ' or a dot .

Expected behavior

PS> '

Actual behavior

PS>\'

Error details

No response

Environment data

PS /home/yen/tmp/PowerShell> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.4.0-preview.3
PSEdition                      Core
GitCommitId                    7.4.0-preview.3
OS                             Linux 6.3.8-arch1-1 PowerShell/PowerShell#1 SMP PREEMPT_DYNAMIC Wed, 14 Jun 2023 20:10:31 +0000
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

I can also reproduce the issue with PowerShell 7.3.4 on Windows 10 22H2.

Visuals

圖片

This is captured with Konsole 23.04.2 and tmux 3.3a. I can reproduce the same issue with PowerShell 7.3.4 on Windows 10 22H2.

yan12125 commented 1 year ago

The issue is gone after Remove-module PSReadline. Probably an issue with PSReadline?

Both PSReadline 2.2.6 and 2.3.1-beta1 have this issue.

237dmitry commented 1 year ago

I had the exactly problem. In my case OSC 9;9 output the last symbol of prompt string, m in prompt below. I do not know why and how but I fixed this by exporting [int] class (no matter what class).

Set-PSReadlineOption -ContinuationPrompt $("`u{20}" * 5)
[console]::WriteLine("`e]12;#0087ff`a")

function Global:Prompt
{
    $null = [int]::new()          # No artefacts. I do not know why.
    $prompt = "`e[38;5;31m `u{ff05} `e]9;9;${PWD}`e\`e[0m"
    return $prompt
}
yan12125 commented 1 year ago

You may want this instead of hacking around $null:

$normalPrompt = "`e[38;5;31m `u{ff05} `e[0m"
$errorPrompt = "`e[91m `u{ff05} `e[0m"
Set-PSReadlineOption -PromptText $normalPrompt, $errorPrompt

From a comment in https://github.com/MicrosoftDocs/terminal/issues/597#issuecomment-1346749542,

IMPORTANT: Make sure there's a printable charater last in the prompt. Otherwise, PSReadline is gonna use the terminating \ here and colorize that if it detects a syntax error

-PromptText explicitly specifies prompts to use for syntax error indication and avoids fragile auto detection.

I have no idea why hacking around $null works, though.

yan12125 commented 1 year ago

Apparently PSReadLine simply cuts a substring since the last non-whitespace character in the prompt: https://github.com/PowerShell/PSReadLine/blob/v2.2.6/PSReadLine/ReadLine.cs#L819. It will be great if OSC commands are parsed and ignored, but that may be far from trivial due to the need of a parser of various escape sequences.

If I were a PowerShell developer, I might close this as WONTFIX :)

GitHub
PSReadLine/PSReadLine/ReadLine.cs at v2.2.6 · PowerShell/PSReadLine
A bash inspired readline implementation for PowerShell - PSReadLine/PSReadLine/ReadLine.cs at v2.2.6 · PowerShell/PSReadLine
237dmitry commented 1 year ago

You may want this

No, I do not want. I showed this example to present a workaround that is inexplicable to me.

daxian-dbw commented 1 year ago

I cannot reproduce the issue with the repro steps described in the issue. The GIF below is from WSL Ubuntu 18.04 with PowerShell 7.4-preview.3 + PSReadLine 2.3.1-beta1. I tried on Windows 11 with both conhost and Windows Terminal, and cannot reproduce too.

repro-ws-2022

@yan12125 and @237dmitry Can either of you please provide a repro that help me reproduce the issue locally?

yan12125 commented 1 year ago

@daxian-dbw For me, the issue happens only when the prompt function is defined in $PROFILE. It does not happend when the function is defined from the command line.

Also, it seems that error prompt is not enabled for you (the last non-whitespace character should become red when there is a syntax error). Could you check if PromptText or ErrorColor in Get-PSReadLineOption results is overridden or not?

daxian-dbw commented 1 year ago

I can reproduce the issue after moving the prompt function to $PROFILE. We will investigate it.

yan12125 commented 1 year ago

Thank you for confirmation. As the reproducer is from official Microsoft docs, how do you think about updating docs to work-around this issue first? https://github.com/MicrosoftDocs/terminal/pull/689

daxian-dbw commented 1 year ago

Unfortunately, we don't own that doc.