-
Notifications
You must be signed in to change notification settings - Fork 207
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1584 from rjmholt/pt-legacy-readline
Re-implement legacy readline support
- Loading branch information
Showing
7 changed files
with
748 additions
and
643 deletions.
There are no files selected for viewing
631 changes: 0 additions & 631 deletions
631
src/PowerShellEditorServices/Services/PowerShell/Console/ConsoleReadLine.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
539 changes: 539 additions & 0 deletions
539
src/PowerShellEditorServices/Services/PowerShell/Console/LegacyReadLine.cs
Large diffs are not rendered by default.
Oops, something went wrong.
63 changes: 63 additions & 0 deletions
63
src/PowerShellEditorServices/Services/PowerShell/Console/PsrlReadLine.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Execution; | ||
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host; | ||
using System.Management.Automation; | ||
using System.Threading; | ||
|
||
namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Console | ||
{ | ||
using System; | ||
|
||
internal class PsrlReadLine : TerminalReadLine | ||
{ | ||
private readonly PSReadLineProxy _psrlProxy; | ||
|
||
private readonly PsesInternalHost _psesHost; | ||
|
||
private readonly EngineIntrinsics _engineIntrinsics; | ||
|
||
#region Constructors | ||
|
||
public PsrlReadLine( | ||
PSReadLineProxy psrlProxy, | ||
PsesInternalHost psesHost, | ||
EngineIntrinsics engineIntrinsics, | ||
Func<bool, ConsoleKeyInfo> readKeyFunc, | ||
Action<CancellationToken> onIdleAction) | ||
{ | ||
_psrlProxy = psrlProxy; | ||
_psesHost = psesHost; | ||
_engineIntrinsics = engineIntrinsics; | ||
_psrlProxy.OverrideReadKey(readKeyFunc); | ||
_psrlProxy.OverrideIdleHandler(onIdleAction); | ||
} | ||
|
||
#endregion | ||
|
||
#region Public Methods | ||
|
||
public override string ReadLine(CancellationToken cancellationToken) | ||
{ | ||
return _psesHost.InvokeDelegate<string>(representation: "ReadLine", new ExecutionOptions { MustRunInForeground = true }, InvokePSReadLine, cancellationToken); | ||
} | ||
|
||
protected override ConsoleKeyInfo ReadKey(CancellationToken cancellationToken) | ||
{ | ||
return ConsoleProxy.ReadKey(intercept: true, cancellationToken); | ||
} | ||
|
||
#endregion | ||
|
||
#region Private Methods | ||
|
||
private string InvokePSReadLine(CancellationToken cancellationToken) | ||
{ | ||
EngineIntrinsics engineIntrinsics = _psesHost.IsRunspacePushed ? null : _engineIntrinsics; | ||
return _psrlProxy.ReadLine(_psesHost.Runspace, engineIntrinsics, cancellationToken, /* lastExecutionStatus */ null); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
src/PowerShellEditorServices/Services/PowerShell/Console/TerminalReadLine.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility; | ||
using System.Management.Automation; | ||
using System.Security; | ||
using System.Threading; | ||
|
||
namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Console | ||
{ | ||
using System; | ||
|
||
internal abstract class TerminalReadLine : IReadLine | ||
{ | ||
public abstract string ReadLine(CancellationToken cancellationToken); | ||
|
||
protected abstract ConsoleKeyInfo ReadKey(CancellationToken cancellationToken); | ||
|
||
public SecureString ReadSecureLine(CancellationToken cancellationToken) | ||
{ | ||
Console.TreatControlCAsInput = true; | ||
int previousInputLength = 0; | ||
SecureString secureString = new SecureString(); | ||
try | ||
{ | ||
bool enterPressed = false; | ||
while (!enterPressed && !cancellationToken.IsCancellationRequested) | ||
{ | ||
ConsoleKeyInfo keyInfo = ReadKey(cancellationToken); | ||
|
||
if (keyInfo.IsCtrlC()) | ||
{ | ||
throw new PipelineStoppedException(); | ||
} | ||
|
||
switch (keyInfo.Key) | ||
{ | ||
case ConsoleKey.Enter: | ||
// Stop the while loop so we can realign the cursor | ||
// and then return the entered string | ||
enterPressed = true; | ||
continue; | ||
|
||
case ConsoleKey.Tab: | ||
break; | ||
|
||
case ConsoleKey.Backspace: | ||
if (secureString.Length > 0) | ||
{ | ||
secureString.RemoveAt(secureString.Length - 1); | ||
} | ||
break; | ||
|
||
default: | ||
if (keyInfo.KeyChar != 0 && !char.IsControl(keyInfo.KeyChar)) | ||
{ | ||
secureString.AppendChar(keyInfo.KeyChar); | ||
} | ||
break; | ||
} | ||
|
||
// Re-render the secure string characters | ||
int currentInputLength = secureString.Length; | ||
int consoleWidth = Console.WindowWidth; | ||
|
||
if (currentInputLength > previousInputLength) | ||
{ | ||
Console.Write('*'); | ||
} | ||
else if (previousInputLength > 0 && currentInputLength < previousInputLength) | ||
{ | ||
int row = ConsoleProxy.GetCursorTop(cancellationToken); | ||
int col = ConsoleProxy.GetCursorLeft(cancellationToken); | ||
|
||
// Back up the cursor before clearing the character | ||
col--; | ||
if (col < 0) | ||
{ | ||
col = consoleWidth - 1; | ||
row--; | ||
} | ||
|
||
Console.SetCursorPosition(col, row); | ||
Console.Write(' '); | ||
Console.SetCursorPosition(col, row); | ||
} | ||
|
||
previousInputLength = currentInputLength; | ||
} | ||
} | ||
finally | ||
{ | ||
Console.TreatControlCAsInput = false; | ||
} | ||
|
||
return secureString; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
src/PowerShellEditorServices/Services/PowerShell/Utility/ConsoleKeyInfoExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
|
||
namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility | ||
{ | ||
internal static class ConsoleKeyInfoExtensions | ||
{ | ||
public static bool IsCtrlC(this ConsoleKeyInfo keyInfo) | ||
{ | ||
if ((int)keyInfo.Key == 3) | ||
{ | ||
return true; | ||
} | ||
|
||
return keyInfo.Key == ConsoleKey.C | ||
&& (keyInfo.Modifiers & ConsoleModifiers.Control) != 0 | ||
&& (keyInfo.Modifiers & ConsoleModifiers.Shift) == 0 | ||
&& (keyInfo.Modifiers & ConsoleModifiers.Alt) == 0; | ||
} | ||
} | ||
} |