PSReadLine icon indicating copy to clipboard operation
PSReadLine copied to clipboard

Newline Handling of [Microsoft.PowerShell.PSConsoleReadLine]::Insert broken in Windows

Open Callidus2000 opened this issue 1 year ago • 1 comments

Prerequisites

  • [X] Write a descriptive title.
  • [X] Make sure you are able to repro it on the latest released version
  • [X] Search the existing issues, especially the pinned issues.

Exception report

N/A

Screenshot

image

image

Environment data

PS Version: 7.3.11 and 7.4
PS HostName: ConsoleHost
PSReadLine Version: 2.3.4
PSReadLine EditMode: Windows
OS: 10.0.19041.1682 (WinBuild.160101.0800)
BufferWidth: 120
BufferHeight: 9001

Steps to reproduce

I've developed a module (CmdFav) which inserts commands into the NEXT prompt. If the command is a multiline command the command string is internally build with StringBuilder.AppendLine(). StringBuilder is using Windows' carriage return + new line (`r`n) instead of just new line (`n). This causes PSConsoleReadLine::Insert to insert visible ^M characters (orange arrow in screenshot) and moves the cursor additional lines to low (red marker in screenshot).

Code to reproduce:

$sb=[System.Text.StringBuilder]::new()
[void]$sb.AppendLine('write-host "Hello"').AppendLine('write-host "World"')
$global:Suggestion = $sb.ToString()
$global:InjectCommand = Register-EngineEvent -SourceIdentifier PowerShell.OnIdle {
    [Microsoft.PowerShell.PSConsoleReadLine]::Insert($global:Suggestion)
    Stop-Job $global:InjectCommand
}

The 'too low cursor' prevents the user to modify the code which is inserted into the prompt in the blank space. If I move the cursor into the blank space and (e.g.) press + the real code is shown, interrupted by the + char.

Expected behavior

  • No ^M visible
  • No blank lines
  • Inserted code should be editable in the right space

Actual behavior

  • Multiline text is postfixed with a ^M
  • After the inserted text additional blank lines are inserted, the cursor is not at the right spot
  • The effective inserted text is hidden in the blank lines and has to be edited there instead in the directly visible part

Callidus2000 avatar Feb 02 '24 08:02 Callidus2000

I do think PSReadLIne should probably convert `r`n to `n when it's passed to Insert

The offset problem only manifests when it's being called like this in the OnIdle.

Compare these:

$global:HistoricalLines = (Get-History -Count 3).CommandLine -join "`n"

function Add-History {
  $global:InjectCommand = Register-EngineEvent -SourceIdentifier PowerShell.OnIdle {
      [Microsoft.PowerShell.PSConsoleReadLine]::Insert($HistoricalLines )
      Stop-Job $global:InjectCommand
  }
}

Set-PSReadLineKeyHandler -Key Alt+h -ScriptBlock {
    [Microsoft.PowerShell.PSConsoleReadLine]::Insert($HistoricalLines)
}

The key handler works exactly how I expected it to, but the OnIdle handler ends up offset by ... however lines there were in the combined history.

Jaykul avatar Feb 03 '24 01:02 Jaykul