8000 Add support for Ctrl-C to interrupt commands, and add multi-line capa… by palladia · Pull Request #613 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Add support for Ctrl-C to interrupt commands, and add multi-line capa… #613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 73 additions & 19 deletions src/Microsoft.PowerShell.Linux.Host/main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@ internal class Listener
/// </summary>
private string partialLine = string.Empty;

/// <summary>
/// To keep track of whether CTRL-C is causing a command abort
/// </summary>
private bool abortCommand = false;

/// <summary>
/// To keep track of whether we are in input mode
/// </summary>
private bool awaitingUserInput = false;

/// <summary>
/// Gets or sets a value indicating whether the host application
/// should exit.
Expand Down Expand Up @@ -342,6 +352,13 @@ private void ExecuteHelper(string cmd, object input)
// Ignore empty command lines.
if (string.IsNullOrEmpty(cmd))
{
if (this.abortCommand)
{
incompleteLine = false;
partialLine = string.Empty;
this.abortCommand = false;
}

return;
}

Expand All @@ -360,14 +377,8 @@ private void ExecuteHelper(string cmd, object input)
{
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
Expand All @@ -394,11 +405,7 @@ private void ExecuteHelper(string cmd, object input)
catch (IncompleteParseException)
{
incompleteLine = true;
cmd = cmd.Trim();
partialLine += cmd;

partialLine += System.Environment.NewLine;

partialLine = $"{partialLine}{cmd}{System.Environment.NewLine}";
}

finally
Expand Down Expand Up @@ -514,6 +521,15 @@ private void Execute(string cmd)
/// ConsoleCancelEventHandler.</param>
private void HandleControlC(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;

if (this.awaitingUserInput)
{
this.abortCommand = true;
this.consoleReadLine.Abort();
return;
}

try
{
lock (this.instanceLock)
Expand All @@ -524,7 +540,6 @@ private void HandleControlC(object sender, ConsoleCancelEventArgs e)
}
}

e.Cancel = true;
}
catch (Exception exception)
{
Expand Down Expand Up @@ -559,7 +574,12 @@ internal void Run()
}

this.myHost.UI.Write(ConsoleColor.White, Console.BackgroundColor, prompt);

// Since Console.TreatControlCAsInput is not implemented, we use awaitingUserInput to
// tell us how control-c should be handled
this.awaitingUserInput = true;
string cmd = consoleReadLine.Read(this.myHost.Runspace, false);
this.awaitingUserInput = false;
this.Execute(cmd);
}
}
Expand All @@ -579,9 +599,23 @@ private void HandleDebuggerStopEvent(object sender, DebuggerStopEventArgs args)
// loop to process Debugger commands.
while (resumeAction == null)
{
Console.Write("[DBG] PS >> ");
string prompt = incompleteLine ? ">> " : "[DBG] PS >> ";
Console.Write(prompt);

this.awaitingUserInput = true;
string command = consoleReadLine.Read(this.myHost.Runspace, true);
Console.WriteLine();
this.awaitingUserInput = false;

if (string.IsNullOrEmpty(command))
{
if (this.abortCommand)
{
incompleteLine = false;
partialLine = string.Empty;
this.abortCommand = false;
}
continue;
}

// Stream output from command processing to console.
var output = new PSDataCollection<PSObject>();
Expand All @@ -600,10 +634,30 @@ private void HandleDebuggerStopEvent(object sender, DebuggerStopEventArgs args)
// 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;
}
Expand Down
Loading
0