diff --git a/src/Microsoft.PowerShell.Linux.Host/main.cs b/src/Microsoft.PowerShell.Linux.Host/main.cs
index 2965c93869..19abe349b2 100644
--- a/src/Microsoft.PowerShell.Linux.Host/main.cs
+++ b/src/Microsoft.PowerShell.Linux.Host/main.cs
@@ -535,6 +535,8 @@ OPTIONS
Console.CancelKeyPress += new ConsoleCancelEventHandler(this.HandleControlC);
//Console.TreatControlCAsInput = false;
+ string initialCommand = String.Empty;
+
// Read commands and run them until the ShouldExit flag is set by
// the user calling "exit".
while (!this.ShouldExit && this.myHost.Runspace != null)
@@ -555,19 +557,24 @@ OPTIONS
this.myHost.UI.Write(ConsoleColor.White, Console.BackgroundColor, prompt);
- bool abort;
- string cmd = consoleReadLine.Read(this.myHost.Runspace, false, out abort);
- if (string.IsNullOrEmpty(cmd))
+ ConsoleReadLine.ReadResult result = consoleReadLine.Read(this.myHost.Runspace, false, initialCommand);
+
+ switch(result.state)
{
- if (abort)
- {
+ case ConsoleReadLine.ReadResult.State.Abort:
incompleteLine = false;
partialLine = string.Empty;
- }
- continue;
+ initialCommand = String.Empty;
+ break;
+ case ConsoleReadLine.ReadResult.State.Redraw:
+ initialCommand = result.command;
+ break;
+ case ConsoleReadLine.ReadResult.State.Complete:
+ default:
+ this.Execute(result.command);
+ initialCommand = String.Empty;
+ break;
}
-
- this.Execute(cmd);
}
}
@@ -583,23 +590,30 @@ OPTIONS
WriteDebuggerStopMessages(args);
+ string initialCommand = String.Empty;
+
// loop to process Debugger commands.
while (resumeAction == null)
{
string prompt = incompleteLine ? ">> " : "[DBG] PS >> ";
Console.Write(prompt);
- bool abort;
- string command = consoleReadLine.Read(this.myHost.Runspace, true, out abort);
-
- if (string.IsNullOrEmpty(command))
+ ConsoleReadLine.ReadResult result = consoleReadLine.Read(this.myHost.Runspace, true, initialCommand);
+
+ switch(result.state)
{
- if (abort)
- {
+ case ConsoleReadLine.ReadResult.State.Abort:
incompleteLine = false;
partialLine = string.Empty;
- }
- continue;
+ initialCommand = String.Empty;
+ continue;
+ case ConsoleReadLine.ReadResult.State.Redraw:
+ initialCommand = result.command;
+ continue;
+ case ConsoleReadLine.ReadResult.State.Complete:
+ default:
+ initialCommand = String.Empty;
+ break;
}
// Stream output from command processing to console.
@@ -622,7 +636,7 @@ OPTIONS
PSCommand psCommand = new PSCommand();
- string fullCommand = incompleteLine ? (partialLine + command) : command;
+ string fullCommand = incompleteLine ? (partialLine + result.command) : result.command;
psCommand.AddScript(fullCommand).AddCommand("Out-String").AddParameter("Stream", true);
incompleteLine = false;
@@ -634,7 +648,7 @@ OPTIONS
catch (IncompleteParseException)
{
incompleteLine = true;
- partialLine = $"{partialLine}{command}{System.Environment.NewLine}";
+ partialLine = $"{partialLine}{result.command}{System.Environment.NewLine}";
}
if (!incompleteLine)
diff --git a/src/Microsoft.PowerShell.Linux.Host/readline.cs b/src/Microsoft.PowerShell.Linux.Host/readline.cs
index 768f15f710..0a2a77cc52 100644
--- a/src/Microsoft.PowerShell.Linux.Host/readline.cs
+++ b/src/Microsoft.PowerShell.Linux.Host/readline.cs
@@ -90,6 +90,29 @@ namespace Microsoft.PowerShell.Linux.Host
///
private string preTabBuffer;
+ ///
+ /// kill buffer used by Ctrl-K and Ctrl-Y
+ ///
+ private string killBuffer = String.Empty;
+
+ ///
+ /// What Read() outputs
+ ///
+ public class ReadResult
+ {
+ public ReadResult(State s, string cmd)
+ {
+ this.command = cmd;
+ this.state = s;
+ Console.TreatControlCAsInput = true;
+ }
+
+ public enum State {Complete, Abort, Redraw}
+
+ public string command;
+ public State state;
+ }
+
///
/// Initializes a new instance of the ConsoleReadLine class.
///
@@ -124,13 +147,20 @@ namespace Microsoft.PowerShell.Linux.Host
/// Read a line of text, colorizing while typing.
///
/// The command line read
- public string Read(Runspace runspace, bool nested, out bool abort)
+ public ReadResult Read(Runspace runspace, bool nested, string initialValue)
{
this.powershell.Runspace = runspace;
this.Initialize();
bool commandComplete = false;
- abort = false;
-// Console.WriteLine("Default value of TreatCtrlCAsInput: {0}", Console.TreatControlCAsInput);
+ bool abort = false;
+ bool redraw = false;
+
+ if (!String.IsNullOrEmpty(initialValue))
+ {
+ this.BufferFromString(initialValue);
+ this.Render();
+ }
+
Console.TreatControlCAsInput = false;
while (true)
@@ -140,12 +170,7 @@ namespace Microsoft.PowerShell.Linux.Host
// Basic Emacs-style readline implementation
if (key.Modifiers.HasFlag(ConsoleModifiers.Control))
{
- commandComplete = ProcessControlKey(key, nested, ref abort);
- if (abort)
- {
- Console.TreatControlCAsInput = true;
- return String.Empty;
- }
+ commandComplete = ProcessControlKey(key, nested, ref abort, ref redraw);
}
else if (key.Modifiers.HasFlag(ConsoleModifiers.Alt))
{
@@ -159,10 +184,19 @@ namespace Microsoft.PowerShell.Linux.Host
previousKeyPress = key;
+ if (abort)
+ {
+ return new ReadResult(ReadResult.State.Abort, String.Empty);
+ }
+
+ if (redraw)
+ {
+ return new ReadResult(ReadResult.State.Redraw, this.buffer.ToString());
+ }
+
if (commandComplete)
{
- Console.TreatControlCAsInput = true;
- return this.OnEnter();
+ return new ReadResult(ReadResult.State.Complete, this.OnEnter());
}
}
}
@@ -170,7 +204,7 @@ namespace Microsoft.PowerShell.Linux.Host
///
/// Process Control-Key combo
///
- private bool ProcessControlKey(ConsoleKeyInfo key, bool nested, ref bool abort)
+ private bool ProcessControlKey(ConsoleKeyInfo key, bool nested, ref bool abort, ref bool redraw)
{
switch (key.Key)
{
@@ -180,12 +214,12 @@ namespace Microsoft.PowerShell.Linux.Host
case ConsoleKey.E:
this.OnEnd();
break;
- // TODO: save buffer, yank with Ctrl-Y
- /*
- case ConsoleKey.K:
- this.OnEscape();
- break;
- */
+ case ConsoleKey.K:
+ this.OnKill();
+ break;
+ case ConsoleKey.Y:
+ this.OnYank();
+ break;
case ConsoleKey.D:
this.OnDelete();
break;
@@ -206,15 +240,12 @@ namespace Microsoft.PowerShell.Linux.Host
this.OnDownArrow(nested);
break;
case ConsoleKey.J:
- this.OnEnter();
- break;
- // TODO: save and restore buffer
- /*
- case ConsoleKey.L:
- this.BufferFromString("clear");
- previousKeyPress = key;
- return this.OnEnter();
- */
+ previousKeyPress = key;
+ return true;
+ case ConsoleKey.L:
+ Console.Clear();
+ redraw = true;
+ return false;
case ConsoleKey.C:
this.Abort();
abort = true;
@@ -688,6 +719,36 @@ namespace Microsoft.PowerShell.Linux.Host
}
}
+ ///
+ /// Ctrl-K was entered.
+ ///
+ private void OnKill()
+ {
+ if (this.buffer.Length > 0 && this.current < this.buffer.Length)
+ {
+ this.killBuffer = this.buffer.ToString().Substring(this.current);
+ this.buffer.Remove(this.current, killBuffer.Length);
+ this.Render();
+ }
+ else
+ {
+ this.killBuffer = String.Empty;
+ }
+ }
+
+ ///
+ /// Ctrl-Y was entered.
+ ///
+ private void OnYank()
+ {
+ if (!String.IsNullOrEmpty(killBuffer))
+ {
+ this.buffer.Insert(this.current, killBuffer);
+ this.current += killBuffer.Length;
+ this.Render();
+ }
+ }
+
///
/// The Backspace key was entered.
///