Pending verification of TreatControlCAsInput

This commit is contained in:
George Fleming 2016-03-15 13:48:31 -07:00
parent d8de5d20bf
commit cc0b25e515
2 changed files with 224 additions and 131 deletions

View file

@ -360,14 +360,8 @@ OPTIONS
{
this.currentPowerShell.Runspace = this.myRunSpace;
if (incompleteLine)
{
this.currentPowerShell.AddScript(partialLine + cmd);
}
else
{
this.currentPowerShell.AddScript(cmd);
}
string fullCommand = incompleteLine ? (partialLine + cmd) : cmd;
this.currentPowerShell.AddScript(fullCommand);
incompleteLine = false;
// Add the default outputter to the end of the pipe and then call the
@ -394,11 +388,7 @@ OPTIONS
catch (IncompleteParseException)
{
incompleteLine = true;
cmd = cmd.Trim();
partialLine += cmd;
partialLine += System.Environment.NewLine;
partialLine = $"{partialLine}{cmd}{System.Environment.NewLine}";
}
finally
@ -526,7 +516,6 @@ OPTIONS
this.currentPowerShell.Stop();
}
}
e.Cancel = true;
}
catch (Exception exception)
@ -565,7 +554,19 @@ OPTIONS
}
this.myHost.UI.Write(ConsoleColor.White, Console.BackgroundColor, prompt);
string cmd = consoleReadLine.Read(this.myHost.Runspace, false);
bool abort;
string cmd = consoleReadLine.Read(this.myHost.Runspace, false, out abort);
if (string.IsNullOrEmpty(cmd))
{
if (abort)
{
incompleteLine = false;
partialLine = string.Empty;
}
continue;
}
this.Execute(cmd);
}
}
@ -585,9 +586,21 @@ OPTIONS
// loop to process Debugger commands.
while (resumeAction == null)
{
Console.Write("[DBG] PS >> ");
string command = consoleReadLine.Read(this.myHost.Runspace, true);
Console.WriteLine();
string prompt = incompleteLine ? ">> " : "[DBG] PS >> ";
Console.Write(prompt);
bool abort;
string command = consoleReadLine.Read(this.myHost.Runspace, true, out abort);
if (string.IsNullOrEmpty(command))
{
if (abort)
{
incompleteLine = false;
partialLine = string.Empty;
}
continue;
}
// Stream output from command processing to console.
var output = new PSDataCollection<PSObject>();
@ -606,10 +619,30 @@ OPTIONS
// command or script. The returned DebuggerCommandResults object will indicate
// whether the command was evaluated by the debugger and if the debugger should
// be released with a specific resume action.
PSCommand psCommand = new PSCommand();
psCommand.AddScript(command).AddCommand("Out-String").AddParameter("Stream", true);
DebuggerCommandResults results = debugger.ProcessCommand(psCommand, output);
if (results.ResumeAction != null)
string fullCommand = incompleteLine ? (partialLine + command) : command;
psCommand.AddScript(fullCommand).AddCommand("Out-String").AddParameter("Stream", true);
incompleteLine = false;
DebuggerCommandResults results = null;
try
{
results = debugger.ProcessCommand(psCommand, output);
}
catch (IncompleteParseException)
{
incompleteLine = true;
partialLine = $"{partialLine}{command}{System.Environment.NewLine}";
}
if (!incompleteLine)
{
partialLine = string.Empty;
}
if (!incompleteLine && results.ResumeAction != null)
{
resumeAction = results.ResumeAction;
}

View file

@ -124,10 +124,14 @@ namespace Microsoft.PowerShell.Linux.Host
/// Read a line of text, colorizing while typing.
/// </summary>
/// <returns>The command line read</returns>
public string Read(Runspace runspace, bool nested)
public string Read(Runspace runspace, bool nested, out bool abort)
{
this.powershell.Runspace = runspace;
this.Initialize();
bool finishedTyping = false;
abort = false;
// Console.WriteLine("Default value of TreatCtrlCAsInput: {0}", Console.TreatControlCAsInput);
// Console.TreatControlCAsInput = false;
while (true)
{
@ -136,129 +140,174 @@ namespace Microsoft.PowerShell.Linux.Host
// Basic Emacs-style readline implementation
if (key.Modifiers.HasFlag(ConsoleModifiers.Control))
{
switch (key.Key)
finishedTyping = ProcessControlKey(key, nested, ref abort);
if (abort)
{
case ConsoleKey.A:
this.OnHome();
break;
case ConsoleKey.E:
this.OnEnd();
break;
// TODO: save buffer, yank with Ctrl-Y
/*
case ConsoleKey.K:
this.OnEscape();
break;
*/
case ConsoleKey.D:
this.OnDelete();
break;
case ConsoleKey.B:
this.OnLeft(key.Modifiers);
break;
case ConsoleKey.F:
this.OnRight(key.Modifiers);
break;
case ConsoleKey.P:
// TODO: incremental search
case ConsoleKey.R:
this.OnUpArrow(nested);
break;
case ConsoleKey.N:
// TODO: incremental search
case ConsoleKey.S:
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();
*/
Console.WriteLine();
// Console.TreatControlCAsInput = true;
return String.Empty;
}
}
else if (key.Modifiers.HasFlag(ConsoleModifiers.Alt))
{
switch (key.Key)
{
// TODO: OnDelete(key)
// TODO: OnBackspace(key)
case ConsoleKey.B:
this.OnLeft(key.Modifiers);
break;
case ConsoleKey.F:
this.OnRight(key.Modifiers);
break;
}
finishedTyping = ProcessAltKey(key);
}
// Unmodified keys
else
{
switch (key.Key)
{
case ConsoleKey.Backspace:
this.OnBackspace();
break;
case ConsoleKey.Delete:
this.OnDelete();
break;
case ConsoleKey.Enter:
previousKeyPress = key;
return this.OnEnter();
case ConsoleKey.RightArrow:
this.OnRight(key.Modifiers);
break;
case ConsoleKey.LeftArrow:
this.OnLeft(key.Modifiers);
break;
case ConsoleKey.Escape:
this.OnEscape();
break;
case ConsoleKey.Home:
this.OnHome();
break;
case ConsoleKey.End:
this.OnEnd();
break;
case ConsoleKey.Tab:
this.OnTab();
break;
case ConsoleKey.UpArrow:
this.OnUpArrow(nested);
break;
case ConsoleKey.DownArrow:
this.OnDownArrow(nested);
break;
// TODO: case ConsoleKey.LeftWindows: not available in linux
// TODO: case ConsoleKey.RightWindows: not available in linux
default:
if (key.KeyChar == '\x0D')
{
goto case ConsoleKey.Enter; // Ctrl-M
}
if (key.KeyChar == '\x08')
{
goto case ConsoleKey.Backspace; // Ctrl-H
}
this.Insert(key.KeyChar);
this.Render();
break;
}
finishedTyping = ProcessNormalKey(key, nested);
}
previousKeyPress = key;
if (finishedTyping)
{
// Console.TreatControlCAsInput = true;
return this.OnEnter();
}
}
}
/// <summary>
/// Process Control-Key combo
/// </summary>
private bool ProcessControlKey(ConsoleKeyInfo key, bool nested, ref bool abort)
{
switch (key.Key)
{
case ConsoleKey.A:
this.OnHome();
break;
case ConsoleKey.E:
this.OnEnd();
break;
// TODO: save buffer, yank with Ctrl-Y
/*
case ConsoleKey.K:
this.OnEscape();
break;
*/
case ConsoleKey.D:
this.OnDelete();
break;
case ConsoleKey.B:
this.OnLeft(key.Modifiers);
break;
case ConsoleKey.F:
this.OnRight(key.Modifiers);
break;
case ConsoleKey.P:
// TODO: incremental search
case ConsoleKey.R:
this.OnUpArrow(nested);
break;
case ConsoleKey.N:
// TODO: incremental search
case ConsoleKey.S:
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();
*/
case ConsoleKey.C:
Console.WriteLine("received Ctrl-C");
this.Abort();
abort = true;
break;
}
return false;
}
/// <summary>
/// Process Alt-Key combo
/// </summary>
private bool ProcessAltKey(ConsoleKeyInfo key)
{
switch (key.Key)
{
// TODO: OnDelete(key)
// TODO: OnBackspace(key)
case ConsoleKey.B:
this.OnLeft(key.Modifiers);
break;
case ConsoleKey.F:
this.OnRight(key.Modifiers);
break;
}
return false;
}
/// <summary>
/// Process normal key
/// </summary>
private bool ProcessNormalKey(ConsoleKeyInfo key, bool nested)
{
switch (key.Key)
{
case ConsoleKey.Backspace:
this.OnBackspace();
break;
case ConsoleKey.Delete:
this.OnDelete();
break;
case ConsoleKey.Enter:
previousKeyPress = key;
return true;
case ConsoleKey.RightArrow:
this.OnRight(key.Modifiers);
break;
case ConsoleKey.LeftArrow:
this.OnLeft(key.Modifiers);
break;
case ConsoleKey.Escape:
this.OnEscape();
break;
case ConsoleKey.Home:
this.OnHome();
break;
case ConsoleKey.End:
this.OnEnd();
break;
case ConsoleKey.Tab:
this.OnTab();
break;
case ConsoleKey.UpArrow:
this.OnUpArrow(nested);
break;
case ConsoleKey.DownArrow:
this.OnDownArrow(nested);
break;
// TODO: case ConsoleKey.LeftWindows: not available in linux
// TODO: case ConsoleKey.RightWindows: not available in linux
default:
if (key.KeyChar == '\x0D')
{
goto case ConsoleKey.Enter; // Ctrl-M
}
if (key.KeyChar == '\x08')
{
goto case ConsoleKey.Backspace; // Ctrl-H
}
this.Insert(key.KeyChar);
this.Render();
break;
}
return false;
}
/// <summary>
/// Initializes the buffer.
/// </summary>
@ -733,6 +782,17 @@ namespace Microsoft.PowerShell.Linux.Host
this.cursor.Place(this.current);
}
/// <summary>
/// Abort current command
/// </summary>
public void Abort()
{
ConsoleColor saveFGColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.Out.WriteLine("^C");
Console.ForegroundColor = saveFGColor;
}
/// <summary>
/// A helper class for maintaining the cursor while editing the command line.
/// </summary>