Skip to content

A few improvements to the interactive debugging experience #401

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

Merged
merged 4 commits into from
Mar 22, 2017
Merged
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
71 changes: 54 additions & 17 deletions src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public DebugAdapter(EditorSession editorSession, ChannelBase serverChannel)
this.editorSession = editorSession;
this.editorSession.PowerShellContext.RunspaceChanged += this.powerShellContext_RunspaceChanged;
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
this.editorSession.PowerShellContext.DebuggerResumed += this.powerShellContext_DebuggerResumed;
}

public DebugAdapter(
Expand All @@ -60,6 +61,7 @@ public DebugAdapter(
this.editorSession.StartDebugSession(hostDetails, profilePaths, editorOperations);
this.editorSession.PowerShellContext.RunspaceChanged += this.powerShellContext_RunspaceChanged;
this.editorSession.DebugService.DebuggerStopped += this.DebugService_DebuggerStopped;
this.editorSession.PowerShellContext.DebuggerResumed += this.powerShellContext_DebuggerResumed;

// The assumption in this overload is that the debugger
// is running in UI-hosted mode, no terminal interface
Expand Down Expand Up @@ -295,6 +297,11 @@ await this.editorSession.PowerShellContext.ExecuteScriptString(
"", false, true);
}

if (this.editorSession.ConsoleService.EnableConsoleRepl)
{
await this.WriteUseIntegratedConsoleMessage();
}

// Send the InitializedEvent so that the debugger will continue
// sending configuration requests
await this.SendEvent(
Expand Down Expand Up @@ -743,23 +750,30 @@ protected async Task HandleEvaluateRequest(

if (isFromRepl)
{
// Check for special commands
if (string.Equals("!ctrlc", evaluateParams.Expression, StringComparison.CurrentCultureIgnoreCase))
if (!this.editorSession.ConsoleService.EnableConsoleRepl)
{
editorSession.PowerShellContext.AbortExecution();
}
else if (string.Equals("!break", evaluateParams.Expression, StringComparison.CurrentCultureIgnoreCase))
{
editorSession.DebugService.Break();
// Check for special commands
if (string.Equals("!ctrlc", evaluateParams.Expression, StringComparison.CurrentCultureIgnoreCase))
{
editorSession.PowerShellContext.AbortExecution();
}
else if (string.Equals("!break", evaluateParams.Expression, StringComparison.CurrentCultureIgnoreCase))
{
editorSession.DebugService.Break();
}
else
{
// Send the input through the console service
var notAwaited =
this.editorSession
.PowerShellContext
.ExecuteScriptString(evaluateParams.Expression, false, true)
.ConfigureAwait(false);
}
}
else
{
// Send the input through the console service
var notAwaited =
this.editorSession
.PowerShellContext
.ExecuteScriptString(evaluateParams.Expression, false, true)
.ConfigureAwait(false);
await this.WriteUseIntegratedConsoleMessage();
}
}
else
Expand All @@ -770,10 +784,11 @@ protected async Task HandleEvaluateRequest(
// has been resumed, return an empty result in this case.
if (editorSession.PowerShellContext.IsDebuggerStopped)
{
await editorSession.DebugService.EvaluateExpression(
evaluateParams.Expression,
evaluateParams.FrameId,
isFromRepl);
result =
await editorSession.DebugService.EvaluateExpression(
evaluateParams.Expression,
evaluateParams.FrameId,
isFromRepl);
}

if (result != null)
Expand All @@ -793,6 +808,17 @@ await requestContext.SendResult(
});
}

private async Task WriteUseIntegratedConsoleMessage()
{
await this.SendEvent(
OutputEvent.Type,
new OutputEventBody
{
Output = "\nThe Debug Console is no longer used for PowerShell debugging. Please use the 'PowerShell Integrated Console' to execute commands in the debugger. Run the 'PowerShell: Show Integrated Console' command to open it.",
Category = "stderr"
});
}

#endregion

#region Event Handlers
Expand Down Expand Up @@ -867,6 +893,17 @@ await this.SendEvent<ContinuedEvent>(
}
}

private async void powerShellContext_DebuggerResumed(object sender, DebuggerResumeAction e)
{
await this.SendEvent(
ContinuedEvent.Type,
new ContinuedEvent
{
AllThreadsContinued = true,
ThreadId = 1
});
}

#endregion
}
}
4 changes: 4 additions & 0 deletions src/PowerShellEditorServices/Console/ConsoleService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ public void CancelReadLoop()
{
if (this.readLineCancellationToken != null)
{
// Set this to false so that Ctrl+C isn't trapped by any
// lingering ReadKey
Console.TreatControlCAsInput = false;

this.readLineCancellationToken.Cancel();
this.readLineCancellationToken = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
PowerShellContext powerShellContext,
Runspace currentRunspace,
PSCommand psCommand,
bool sendOutputToHost);
bool sendOutputToHost,
out DebuggerResumeAction? debuggerResumeAction);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
PowerShellContext powerShellContext,
Runspace currentRunspace,
PSCommand psCommand,
bool sendOutputToHost)
bool sendOutputToHost,
out DebuggerResumeAction? debuggerResumeAction)
{
IEnumerable<TResult> executionResult = null;

Expand Down Expand Up @@ -63,6 +64,9 @@ public IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
}
}

// No DebuggerResumeAction result for PowerShell v3
debuggerResumeAction = null;

return executionResult;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ public IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
PowerShellContext powerShellContext,
Runspace currentRunspace,
PSCommand psCommand,
bool sendOutputToHost)
bool sendOutputToHost,
out DebuggerResumeAction? debuggerResumeAction)
{
debuggerResumeAction = null;
PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();

#if !PowerShellv3
Expand All @@ -56,6 +58,10 @@ public IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
currentRunspace.Debugger.ProcessCommand(
psCommand,
outputCollection);

// Pass along the debugger's resume action if the user's
// command caused one to be returned
debuggerResumeAction = commandResults.ResumeAction;
#endif

IEnumerable<TResult> results = null;
Expand Down
27 changes: 19 additions & 8 deletions src/PowerShellEditorServices/Session/PowerShellContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -699,15 +699,16 @@ public async Task ExecuteScriptWithArgs(string script, string arguments = null,
// Related to issue #123.
if (File.Exists(script) || File.Exists(scriptAbsPath))
{
script = EscapePath(script, escapeSpaces: true);
// Dot-source the launched script path
script = ". " + EscapePath(script, escapeSpaces: true);
}

launchedScript = script + " " + arguments;
command.AddScript(launchedScript);
command.AddScript(launchedScript, false);
}
else
{
command.AddCommand(script);
command.AddCommand(script, false);
}

if (writeInputToHost)
Expand Down Expand Up @@ -1088,11 +1089,21 @@ private IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(PSCommand psComma
"Attempting to execute command(s) in the debugger:\r\n\r\n{0}",
GetStringForPSCommand(psCommand)));

return this.versionSpecificOperations.ExecuteCommandInDebugger<TResult>(
this,
this.CurrentRunspace.Runspace,
psCommand,
sendOutputToHost);
IEnumerable<TResult> output =
this.versionSpecificOperations.ExecuteCommandInDebugger<TResult>(
this,
this.CurrentRunspace.Runspace,
psCommand,
sendOutputToHost,
out DebuggerResumeAction? debuggerResumeAction);

if (debuggerResumeAction.HasValue)
{
// Resume the debugger with the specificed action
this.ResumeDebugger(debuggerResumeAction.Value);
}

return output;
}

internal void WriteOutput(string outputString, bool includeNewLine)
Expand Down