Pending verification of TreatControlCAsInput
This commit is contained in:
parent
d8de5d20bf
commit
cc0b25e515
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue