PowerShell / PSReadLine

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

Multi-line text allows parts of Line 2 to bleed into Line 4 (if line 4 length is shorter than line 2 length) #3447

Open DEberhardt opened 1 year ago

DEberhardt commented 1 year ago

Prerequisites

Exception report

No Exception, just a visual bug / Bleed-through of text

Previous analysis with Jan on Oh-my-posh: https://github.com/JanDeDobbeleer/oh-my-posh/issues/2911

Screenshot

image

Environment data

PS Version: 5.1.22621.436
PS HostName: ConsoleHost
PSReadLine Version: 2.2.6
PSReadLine EditMode: Windows
OS: 10.0.22621.1 (WinBuild.160101.0800)
BufferWidth: 345
BufferHeight: 47

Steps to reproduce

Select multi-line text, like this one:

function Get-StrictMode {
  # returns the currently set StrictMode version 1, 2, 3
  # or 0 if StrictMode is off.
  try { $xyz = @(1); $null = ($null -eq $xyz[2]) }
  catch { return 3 }

  try { 'Not-a-Date'.Year }
  catch { return 2 }

  try { $null = ($undefined -gt 1) }
  catch { return 1 }

  return 0
}

Paste it into a session that has Oh-my-posh loaded with TransientPrompt enabled, the output is this:

[2022-10-08 15:48:44]❯ function Get-StrictMode {                                                                                                                                                                                                                                                                                                         >   # returns the currently set StrictMode version 1, 2, 3                                                                                                                                                                                                                                                                                               >   # or 0 if StrictMode is off.                                                                                                                                                                                                                                                                                                                         
>   try { $xyz = @(1); $null = ($null -eq $xyz[2]) }, 2, 3                                                                                                                                                                                                                                                                                               
>   catch { return 3 }de is off.
>   try { $xyz = @(1); $null = ($null -eq $xyz[2]) }
>   try { 'Not-a-Date'.Year }
>   catch { return 2 }
>   try { 'Not-a-Date'.Year }
>   try { $null = ($undefined -gt 1) }
>   catch { return 1 }
>   try { $null = ($undefined -gt 1) }
>   return 0return 1 }
> }

Expected behavior

Output displayed as-is

Actual behavior

On line 4, the text "de is off." is repeated from line 2. I could observe this on other terminals (Windows Terminal) with multi-line text as well.

This has no impact on the execution, but is a visual bug on the terminal.

DEberhardt commented 1 year ago

Now that I see my screenshot, I noticed that most of the output is garbled/repeated...

daxian-dbw commented 1 year ago

Are you pasting with mouse right click? Using Ctrl+v for pasting should give you the expected result. The right-clicking issue is old, tracking by #579.

DEberhardt commented 1 year ago

I am indeed right clicking. - didn't know this was known for that long 😉

DEberhardt commented 1 year ago

This seems to be indifferent to the Right-Click VS CTRL+V method, at least in PowerShell 7 in VSCode: image

here my local environment:

PowerShell Module PathsC:\Users\David\Documents\PowerShell\Modules
C:\Program Files\PowerShell\Modules
c:\program files\windowsapps\microsoft.powershell_7.2.6.0_x64__8wekyb3d8bbwe\Modules
C:\Program Files\WindowsPowerShell\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
c:\Users\David\.vscode\extensions\ms-vscode.powershell-preview-2022.10.0\modules

PowerShell Version Table

Name                           Value
----                           -----
PSVersion                      7.2.6
PSEdition                      Core
GitCommitId                    7.2.6
OS                             Microsoft Windows 10.0.22623
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PowerShell Host

Name             : Visual Studio Code Host
Version          : 2022.10.0
InstanceId       : c3995ce1-641a-4bb4-bd0b-0db8a86102eb
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-GB
CurrentUICulture : en-GB
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

Installed NET Frameworks

PSChildName                      Version        Release
-----------                      -------        -------
v2.0.50727                       2.0.50727.4927
v3.0                             3.0.30729.4926
Windows Communication Foundation 3.0.4506.4926
Windows Presentation Foundation  3.0.6920.4902
v3.5                             3.5.30729.4926
Client                           4.8.09032      533320
Full                             4.8.09032      533320
Client                           4.0.0.0

I can reproduce the same in PowerShell 5.1 (and 7.2.6) in Windows Terminal

daxian-dbw commented 1 year ago

This seems to be indifferent to the Right-Click VS CTRL+V method, at least in PowerShell 7 in VSCode: I can reproduce the same in PowerShell 5.1 (and 7.2.6) in Windows Terminal

The given information is a little inconsistent. Can you confirm if this happens with both VSCode integrated console and pwsh.exe in Windows Terminal?

Paste it into a session that has Oh-my-posh loaded with TransientPrompt enabled

Can you please provide the step to enable TransientPrompt?

DEberhardt commented 1 year ago

Adoption of the transient prompt is not yet very widespread, so I have uploaded my own file for convenience ParagnosterPlus2.omp.zip AFAIK, having a Theme that supports it and running Enable-PoshTransientPrompt (once) did the trick for me.

I have repo'd in the following terminals:

The above environment was taken from the pwsh session in Windows Terminal

My VsCode terminals

    "terminal.integrated.profiles.windows": {
        "PowerShell 5": {
            "path": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
            "args": [
                "-noExit"
            ]
        },
        "PowerShell 7": {
            "path": "pwsh.exe",
            "args": [
                "-noExit"
            ]
        },
    },
cveld commented 1 year ago

In my case I am using a multiline oh-my-posh prompt. The issue occurs as well when running some command that is spanning across multiple lines. Only the first line is cleaned up.

oh-my-posh-line1> oh-my-posh-line2> az rest --uri /subscriptions/mysubscription/providers/Microsoft.Web/locations/westeurope/managedApis/sap?api-version=2016-06-01 With 06-01 on the second line, pressing enter, leaves 06-01 on the second line:

transient-prompt> az rest --uri /subscriptions/mysubscription/providers/Microsoft.Web/locations/westeurope/managedApis/sap?api-version=2016-06-01 06-01

I guess the transient writing only clears the first oh-my-posh-line1> line but forgets that theoretically the command can span multiple lines beyond.

Second example: When executing

echo ${
   "carl" = "3"
}

Only echo ${ gets cleared. I.e. only the first line gets cleared, leaving the rest cluttering the output.

cveld commented 1 year ago

Some screenshots

image

image

cveld commented 1 year ago

@daxian-dbw I see you tagged this issue with the label "resolution-duplicate", but isn't the issue I am experiencing different? Should I create a new issue for my issue?

daxian-dbw commented 1 year ago

@cveld The issue you described here is different from the original issue that @DEberhardt opened.

With 06-01 on the second line, pressing enter, leaves 06-01 on the second line:

It looks oh-my-posh register its own handler for the key Enter: https://github.com/JanDeDobbeleer/oh-my-posh/blob/e45cd7ea17636a2d6c527eeda7d9b609c21c2851/src/shell/scripts/omp.ps1#L134-L159

I think you should open an issue in the oh-my-posh repo instead.

JanDeDobbeleer commented 1 year ago

@daxian-dbw I just had a good debug session on our end to see what could cause the issue but without success. Yes, we register a handler for the Enter key, but it doesn't do magical things other than already fix 2 bugs (suggestion list troubles and UTF-8 problems when using InvokePrompt()) coming from PSReadLine.

All we want to do is display a different, more compact prompt on enter. This keeps the historical view in the terminal nice and clean, as you don't necessarily care about the previous state of your folder etc going forward. Therefore we make use of InvokePrompt(), which I believe serves this use-case just right. In our prompt function we evaluate the lines of the newly generated prompt every time, so if it's currently 2 lines, but the transient prompt is only 1 line, we set the extraPromptLineCount correctly. This implies it toggles between 0 or more every time we call InvokePrompt().

Provided this is what PSReadLine needs, it is solely responsible to reload the prompt correctly and display the current command and next prompt without issues (on AcceptLine() here), regardless of wether or not the user is in a prediction list, regular command, etc. That's why we have and rely on PSReadLine in the first place.

Unless you can point to what we should not or be doing differently in our handler, this is a bug for PSReadLine.

DEberhardt commented 6 months ago

This seems to be the same root cause: https://github.com/JanDeDobbeleer/oh-my-posh/issues/4710