From 3c2ec835c063d4ace4b4b6f92928143d52d6237c Mon Sep 17 00:00:00 2001 From: George Fleming Date: Thu, 18 Feb 2016 15:32:31 -0800 Subject: [PATCH 1/3] New changes to readline.cs to improve tab-completion and up/down arrow --- .../readline.cs | 184 +++++++++--------- 1 file changed, 97 insertions(+), 87 deletions(-) diff --git a/src/Microsoft.PowerShell.Linux.Host/readline.cs b/src/Microsoft.PowerShell.Linux.Host/readline.cs index 75d7ee5a81..17b7582f08 100644 --- a/src/Microsoft.PowerShell.Linux.Host/readline.cs +++ b/src/Microsoft.PowerShell.Linux.Host/readline.cs @@ -2,6 +2,7 @@ namespace Microsoft.PowerShell.Linux.Host { using System; using System.Collections.ObjectModel; + using System.IO; using System.Management.Automation; using System.Management.Automation.Runspaces; using System.Text; @@ -79,6 +80,11 @@ namespace Microsoft.PowerShell.Linux.Host /// private ConsoleColor defaultColor = ConsoleColor.White; + /// + /// To keep track of whether we have hit "enter" key since last arrow up/down key + /// + private bool newHistory = false; + /// /// Initializes a new instance of the ConsoleReadLine class. /// @@ -244,17 +250,18 @@ namespace Microsoft.PowerShell.Linux.Host string tabResult = cmdCompleteOpt.CompletionMatches[tabCompletionPos].CompletionText; + // To match behavior on Windows + bool moveLeftOneSpace = false; + if (cmdCompleteOpt.CompletionMatches[tabCompletionPos].ResultType == CompletionResultType.ProviderContainer) + { + tabResult = GetReplacementTextForDirectory(tabResult, ref moveLeftOneSpace); + } + tabCompletionPos++; //if there is a command for the user before the uncompleted option if (!String.IsNullOrEmpty(tabResult)) { - //handle file path slashes - if (tabResult.Contains(".\\")) - { - tabResult = tabResult.Replace(".\\", ""); - } - var replaceIndex = cmdCompleteOpt.ReplacementIndex; string replaceBuffer = this.buffer.ToString(); @@ -275,10 +282,48 @@ namespace Microsoft.PowerShell.Linux.Host BufferFromString(tabResult); this.Render(); + + if (moveLeftOneSpace) + { + MoveLeft(); + } } } //end of OnTab() + /// + /// Helper function to add trailing slash to directories + /// + private static string GetReplacementTextForDirectory(string replacementText, ref bool moveLeftOneSpace) + { + string separator = Path.DirectorySeparatorChar.ToString(); + const string singleQuote = "'"; + const string doubleQuote = "\""; + + if (!replacementText.EndsWith(separator, StringComparison.Ordinal)) + { + if (replacementText.EndsWith(separator + singleQuote, StringComparison.Ordinal) + || replacementText.EndsWith(separator + doubleQuote, StringComparison.Ordinal)) + { + moveLeftOneSpace = true; + return replacementText; + } + else if (replacementText.EndsWith(singleQuote, StringComparison.Ordinal) + || replacementText.EndsWith(doubleQuote, StringComparison.Ordinal)) + { + var len = replacementText.Length; + char quoteChar = replacementText[len - 1]; + replacementText = replacementText.Substring(0, len - 1) + separator + quoteChar; + moveLeftOneSpace = true; + } + else + { + replacementText = replacementText + separator; + } + } + return replacementText; + } + /// /// Set buffer to a string rather than inserting char by char /// @@ -311,100 +356,64 @@ namespace Microsoft.PowerShell.Linux.Host } /// - /// The up arrow was pressed to retrieve history + /// The down arrow was pressed to retrieve history /// - private void OnDownArrow() { - + private void OnDownArrow() + { if (historyResult == null) { return; } - if (historyIndex == historyResult.Count) - { - OnEscape(); - } - historyIndex++; - try + if (historyIndex >= historyResult.Count) { + OnEscape(); + historyIndex = historyResult.Count; + return; + } + + BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); + this.Render(); + + this.newHistory = false; + } + + /// + /// Changes the history queue when the up arrow is pressed + /// + private void OnUpArrow() + { + if (this.newHistory) + { + // get the history + using (Pipeline pipeline = this.powershell.Runspace.CreatePipeline("Get-History")) + { + historyResult = pipeline.Invoke(); + } + + historyIndex = historyResult.Count -1; + if (historyIndex >= 0) + { + BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); + this.Render(); + } + } + else + { + if ( historyIndex == 0 || historyResult.Count == 0 ) + { + return; + } + + historyIndex--; + BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); this.Render(); } - catch - { - return; - } - } - - /// - /// Changes the history queue when the down arrow is pressed - /// - private void OnUpArrow() - { - - try{ - if ((previousKeyPress.Key != ConsoleKey.DownArrow && previousKeyPress.Key != ConsoleKey.UpArrow) || previousKeyPress.Key == ConsoleKey.Enter) - { - //first time getting the history - using (Pipeline pipeline = this.powershell.Runspace.CreatePipeline("Get-History")) - { - historyResult = pipeline.Invoke(); - } - - try - { - historyIndex = historyResult.Count -1; - BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); - this.Render(); - historyIndex--; - } - - catch - { - return; - } - - } - - else - { - if (historyIndex > historyResult.Count) //we hit the blank prompt using the down arrow - { - historyIndex = historyResult.Count -1; - } - - if ( historyIndex < 0 ) - { - historyIndex = 0; - } - - try - { - BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); - this.Render(); - - if ( historyIndex == 0 ) - { - return; - } - - else - { - historyIndex--; - } - } - - catch - { - return; - } - } - } - - catch { return;} + this.newHistory = false; } /// @@ -526,6 +535,7 @@ namespace Microsoft.PowerShell.Linux.Host /// A newline character. private string OnEnter() { + this.newHistory = true; Console.Out.WriteLine(); return this.buffer.ToString(); } From 23bdcdd330a34c13c4ceaf917332c68be66f7476 Mon Sep 17 00:00:00 2001 From: George Fleming Date: Thu, 18 Feb 2016 15:32:46 -0800 Subject: [PATCH 2/3] Adding monad branch --- src/monad | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/monad b/src/monad index 3aec819b82..365bd20cf4 160000 --- a/src/monad +++ b/src/monad @@ -1 +1 @@ -Subproject commit 3aec819b82f53b84824b69702975242d6568ca0d +Subproject commit 365bd20cf400f5c8dd2ff9d8894e16a046248d0f From 8cbb08964cc2d3d78c410ed7061902037e1d77b9 Mon Sep 17 00:00:00 2001 From: George Fleming Date: Fri, 19 Feb 2016 09:10:40 -0800 Subject: [PATCH 3/3] Fix a special down arrow scenario --- .../readline.cs | 59 +++++++++++-------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/src/Microsoft.PowerShell.Linux.Host/readline.cs b/src/Microsoft.PowerShell.Linux.Host/readline.cs index 17b7582f08..72edebee10 100644 --- a/src/Microsoft.PowerShell.Linux.Host/readline.cs +++ b/src/Microsoft.PowerShell.Linux.Host/readline.cs @@ -360,22 +360,31 @@ namespace Microsoft.PowerShell.Linux.Host /// private void OnDownArrow() { - if (historyResult == null) - { - return; - } - - historyIndex++; - - if (historyIndex >= historyResult.Count) + if (this.newHistory) { + GetHistory(); OnEscape(); historyIndex = historyResult.Count; - return; } + else + { + if ( historyResult == null) + { + return; + } - BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); - this.Render(); + historyIndex++; + + if (historyIndex >= historyResult.Count) + { + OnEscape(); + historyIndex = historyResult.Count; + return; + } + + BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); + this.Render(); + } this.newHistory = false; } @@ -387,22 +396,15 @@ namespace Microsoft.PowerShell.Linux.Host { if (this.newHistory) { - // get the history - using (Pipeline pipeline = this.powershell.Runspace.CreatePipeline("Get-History")) - { - historyResult = pipeline.Invoke(); - } + GetHistory(); + historyIndex = historyResult.Count - 1; - historyIndex = historyResult.Count -1; - if (historyIndex >= 0) - { - BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); - this.Render(); - } + BufferFromString(historyResult[historyIndex].Members["CommandLine"].Value.ToString()); + this.Render(); } else { - if ( historyIndex == 0 || historyResult.Count == 0 ) + if ( historyResult == null || historyIndex == 0) { return; } @@ -416,6 +418,17 @@ namespace Microsoft.PowerShell.Linux.Host this.newHistory = false; } + /// + /// Helper function to get command history + /// + private void GetHistory() + { + using (Pipeline pipeline = this.powershell.Runspace.CreatePipeline("Get-History")) + { + historyResult = pipeline.Invoke(); + } + } + /// /// Moves to the left of the cursor position. ///