diff --git a/src/Microsoft.PowerShell.Linux.Host/main.cs b/src/Microsoft.PowerShell.Linux.Host/main.cs
index b4847dc60a..028913dc27 100644
--- a/src/Microsoft.PowerShell.Linux.Host/main.cs
+++ b/src/Microsoft.PowerShell.Linux.Host/main.cs
@@ -109,6 +109,9 @@ OPTIONS
}
// TODO: check for input on stdin
+ ConsoleColor InitialForegroundColor = Console.ForegroundColor;
+ ConsoleColor InitialBackgroundColor = Console.BackgroundColor;
+
// Create the listener and run it
Listener listener = new Listener(initialScript, loadProfiles);
@@ -118,6 +121,9 @@ OPTIONS
listener.Run();
}
+ Console.ForegroundColor = InitialForegroundColor;
+ Console.BackgroundColor = InitialBackgroundColor;
+
// Exit with the desired exit code that was set by the exit command.
// The exit code is set in the host by the MyHost.SetShouldExit() method.
System.Environment.Exit(listener.ExitCode);
@@ -129,7 +135,7 @@ OPTIONS
///
/// Used to read user input.
///
- internal ConsoleReadLine consoleReadLine = new ConsoleReadLine();
+ internal ConsoleReadLine consoleReadLine;
///
/// Holds a reference to the runspace for this interpeter.
@@ -213,6 +219,7 @@ OPTIONS
InitialSessionState iss = InitialSessionState.CreateDefault2();
this.myRunSpace = RunspaceFactory.CreateRunspace(this.myHost, iss);
this.myRunSpace.Open();
+ this.consoleReadLine = new ConsoleReadLine(this.myHost.Runspace, this.myHost.UI);
if (this.myRunSpace.Debugger != null)
{
@@ -222,7 +229,6 @@ OPTIONS
// feature. In order to debug Workflow script functions the debugger
// DebugMode must include the DebugModes.LocalScript flag.
this.myRunSpace.Debugger.SetDebugMode(DebugModes.LocalScript);
-
}
if (loadProfiles)
@@ -554,9 +560,9 @@ OPTIONS
prompt = "PS> ";
}
- this.myHost.UI.Write(ConsoleColor.White, Console.BackgroundColor, prompt);
+ this.myHost.UI.Write(prompt);
- ConsoleReadLine.ReadResult result = consoleReadLine.Read(this.myHost.Runspace, this.myHost.UI, false, initialCommand);
+ ConsoleReadLine.ReadResult result = consoleReadLine.Read(false, initialCommand);
switch(result.state)
{
@@ -597,7 +603,7 @@ OPTIONS
string prompt = incompleteLine ? ">> " : "[DBG] PS >> ";
this.myHost.UI.Write(prompt);
- ConsoleReadLine.ReadResult result = consoleReadLine.Read(this.myHost.Runspace, this.myHost.UI, true, initialCommand);
+ ConsoleReadLine.ReadResult result = consoleReadLine.Read(true, initialCommand);
switch(result.state)
{
diff --git a/src/Microsoft.PowerShell.Linux.Host/readline.cs b/src/Microsoft.PowerShell.Linux.Host/readline.cs
index b8695f2b65..f44bdbb764 100644
--- a/src/Microsoft.PowerShell.Linux.Host/readline.cs
+++ b/src/Microsoft.PowerShell.Linux.Host/readline.cs
@@ -101,6 +101,21 @@ namespace Microsoft.PowerShell.Linux.Host
///
private string killBuffer = String.Empty;
+ ///
+ /// Indicator that command input is complete
+ ///
+ private bool commandComplete;
+
+ ///
+ /// Indicator that current command is to be aborted
+ ///
+ private bool abort;
+
+ ///
+ /// Indicator that we are to redraw current command
+ ///
+ private bool redraw;
+
///
/// What Read() outputs
///
@@ -122,7 +137,7 @@ namespace Microsoft.PowerShell.Linux.Host
///
/// Initializes a new instance of the ConsoleReadLine class.
///
- public ConsoleReadLine()
+ public ConsoleReadLine(Runspace runspace, PSHostUserInterface hostUI)
{
this.tokenColors = new ConsoleColor[]
{
@@ -147,20 +162,17 @@ namespace Microsoft.PowerShell.Linux.Host
this.defaultColor, // LineContinuation
this.defaultColor, // Position
};
+ this.powershell.Runspace = runspace;
+ this.ui = hostUI;
}
///
/// Read a line of text, colorizing while typing.
///
/// The command line read
- public ReadResult Read(Runspace runspace, PSHostUserInterface hostUI, bool nested, string initialValue)
+ public ReadResult Read(bool nested, string initialValue)
{
- this.powershell.Runspace = runspace;
- this.ui = hostUI;
this.Initialize();
- bool commandComplete = false;
- bool abort = false;
- bool redraw = false;
if (!String.IsNullOrEmpty(initialValue))
{
@@ -168,28 +180,34 @@ namespace Microsoft.PowerShell.Linux.Host
this.Render();
}
- Console.TreatControlCAsInput = true;
-
while (true)
{
- ConsoleKeyInfo key = Console.ReadKey(true);
+ try
+ {
+ ConsoleKeyInfo key = Console.ReadKey(true);
- // Basic Emacs-style readline implementation
- if (key.Modifiers.HasFlag(ConsoleModifiers.Control))
- {
- commandComplete = ProcessControlKey(key, nested, ref abort, ref redraw);
- }
- else if (key.Modifiers.HasFlag(ConsoleModifiers.Alt))
- {
- commandComplete = ProcessAltKey(key);
- }
- // Unmodified keys
- else
- {
- commandComplete = ProcessNormalKey(key, nested);
- }
+ // Basic Emacs-style readline implementation
+ if (key.Modifiers.HasFlag(ConsoleModifiers.Control))
+ {
+ commandComplete = ProcessControlKey(key, nested);
+ }
+ else if (key.Modifiers.HasFlag(ConsoleModifiers.Alt))
+ {
+ commandComplete = ProcessAltKey(key);
+ }
+ // Unmodified keys
+ else
+ {
+ commandComplete = ProcessNormalKey(key, nested);
+ }
- previousKeyPress = key;
+ previousKeyPress = key;
+ }
+ catch
+ {
+ // if anything goes wrong, abort
+ abort = true;
+ }
if (abort)
{
@@ -211,7 +229,7 @@ namespace Microsoft.PowerShell.Linux.Host
///
/// Process Control-Key combo
///
- private bool ProcessControlKey(ConsoleKeyInfo key, bool nested, ref bool abort, ref bool redraw)
+ private bool ProcessControlKey(ConsoleKeyInfo key, bool nested)
{
switch (key.Key)
{
@@ -237,7 +255,7 @@ namespace Microsoft.PowerShell.Linux.Host
this.OnRight(false);
break;
case ConsoleKey.R:
- return this.ReverseSearch(nested, ref abort);
+ return this.ReverseSearch(nested);
case ConsoleKey.J:
previousKeyPress = key;
return true;
@@ -247,7 +265,6 @@ namespace Microsoft.PowerShell.Linux.Host
return false;
case ConsoleKey.C:
this.Abort();
- abort = true;
return true;
case ConsoleKey.P:
this.OnUpArrow(nested);
@@ -365,6 +382,10 @@ namespace Microsoft.PowerShell.Linux.Host
this.current = 0;
this.rendered = 0;
this.cursor = new Cursor();
+ this.commandComplete = false;
+ this.abort = false;
+ this.redraw = false;
+ Console.TreatControlCAsInput = true;
}
///
@@ -592,7 +613,7 @@ namespace Microsoft.PowerShell.Linux.Host
///
/// Reverse search through history
///
- private bool ReverseSearch(bool nested, ref bool abort)
+ private bool ReverseSearch(bool nested)
{
GetHistory(nested);
@@ -609,17 +630,12 @@ namespace Microsoft.PowerShell.Linux.Host
while (true)
{
OnEscape();
- ConsoleColor saveFGColor = Console.ForegroundColor;
ui.Write("(");
- Console.ForegroundColor = ConsoleColor.Red;
- ui.Write(String.Format("{0}", failed));
- Console.ForegroundColor = saveFGColor;
- ui.Write(String.Format("reverse-i-search)'{0}", searchString.ToString()));
+ ui.Write(ConsoleColor.Red, Console.BackgroundColor, $"{failed}");
+ ui.Write($"bck-i-search)'{searchString}");
this.current = this.cursor.GetPosition();
ui.Write("': ");
- Console.ForegroundColor = ConsoleColor.Green;
- ui.Write(String.Format("{0}", searchResult));
- Console.ForegroundColor = saveFGColor;
+ ui.Write(ConsoleColor.Green, Console.BackgroundColor, $"{searchResult}");
this.rendered = this.cursor.GetPosition();
this.cursor.Place(this.current);
@@ -635,7 +651,6 @@ namespace Microsoft.PowerShell.Linux.Host
break;
case ConsoleKey.C:
Abort();
- abort = true;
return true;
default:
terminateSearch = true;
@@ -695,7 +710,7 @@ namespace Microsoft.PowerShell.Linux.Host
string result = reverseSearchHistory(searchString.ToString(), ref searchPos);
if (String.IsNullOrEmpty(result))
{
- failed = "failed ";
+ failed = "failed-";
}
else
{
@@ -1024,6 +1039,7 @@ namespace Microsoft.PowerShell.Linux.Host
Console.ForegroundColor = ConsoleColor.Red;
ui.WriteLine("^C");
Console.ForegroundColor = saveFGColor;
+ this.abort = true;
}
///