From 5e9c31107c4fdbc8671e504d30bd20065b01eace Mon Sep 17 00:00:00 2001 From: George Fleming Date: Wed, 23 Mar 2016 16:17:06 -0700 Subject: [PATCH] Changes per Andy comments, and add revert of colors at end of PS --- src/Microsoft.PowerShell.Linux.Host/main.cs | 16 +++- .../readline.cs | 94 +++++++++++-------- 2 files changed, 66 insertions(+), 44 deletions(-) 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; } ///