From 1913244fad53144e618a0eb12d1d9791be19aeb6 Mon Sep 17 00:00:00 2001 From: "Jason Shirk (POWERSHELL)" Date: Wed, 21 Sep 2016 15:01:33 -0700 Subject: [PATCH] Fix `powershell -Command -` handling of backspace PowerShell can be started with input redirected in different scenarios. `powershell -Command -` is one scenario where commands are sent to PowerShell, but this is not a interactive shell scenario, it's really a server to run commands from some other process. `powershell -File -` or just regular redirected input means PowerShell is an interactive shell, but command line editing must be done via the redirected standard input handle instead of interacting directly with a console handle. In this scenario, we want to provide a good editing experience. Today, we provide the bare minimum, supporting backspace but no cursor movement. The bug here is that backspace was treated as a backspace in the server mode but should not have been. --- .../host/msh/ConsoleHostUserInterface.cs | 4 +++- test/powershell/Host/ConsoleHost.Tests.ps1 | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs index 6c4006e7c8..478d05902e 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterface.cs @@ -1590,7 +1590,9 @@ namespace Microsoft.PowerShell break; } - if (c == '\b') + // If NoPrompt is true, we are in a sort of server mode where we shouldn't + // do anything like edit the command line - every character is part of the input. + if (c == '\b' && !NoPrompt) { sb.Remove(sb.Length - 1, 1); } diff --git a/test/powershell/Host/ConsoleHost.Tests.ps1 b/test/powershell/Host/ConsoleHost.Tests.ps1 index b756f9bb2e..63f7e820f9 100644 --- a/test/powershell/Host/ConsoleHost.Tests.ps1 +++ b/test/powershell/Host/ConsoleHost.Tests.ps1 @@ -227,6 +227,12 @@ Describe "ConsoleHost unit tests" -tags "Feature" { $process.StandardInput.Write("1+2`n") $process.StandardOutput.ReadLine() | Should Be "PS> 1+2" $process.StandardOutput.ReadLine() | Should Be "3" + + # Backspace should work as expected + $process.StandardInput.Write("1+2`b3`n") + # A real console should render 2`b3 as just 3, but we're just capturing exactly what is written + $process.StandardOutput.ReadLine() | Should Be "PS> 1+2`b3" + $process.StandardOutput.ReadLine() | Should Be "4" $process.StandardInput.Close() $process.StandardOutput.ReadToEnd() | Should Be "PS> " EnsureChildHasExited $process @@ -279,6 +285,10 @@ foo "@) $process.StandardOutput.ReadLine() | Should Be "in foo" + # Backspace sent through stdin should be in the final string + $process.StandardInput.Write("`"a`bc`".Length`n") + $process.StandardOutput.ReadLine() | Should Be "3" + # Last command with no newline - should be accepted and # produce output after closing stdin. $process.StandardInput.Write('22 + 22')