From 89163a5f5911a943de52919d538fc9ad6fc4d377 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 18 Apr 2018 15:12:54 +0200 Subject: [PATCH] debug: terminate thread as a context menu and command palette action fixes #29549 --- .../parts/debug/browser/debugActions.ts | 21 +++++++++++++++++++ src/vs/workbench/parts/debug/common/debug.ts | 2 ++ .../parts/debug/common/debugModel.ts | 4 ++++ .../debug/electron-browser/callStackView.ts | 6 +++++- .../electron-browser/debug.contribution.ts | 3 ++- .../debug/electron-browser/rawDebugSession.ts | 4 ++++ .../parts/debug/test/common/mockDebug.ts | 5 +++++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts index 5b4232955dc..51849684254 100644 --- a/src/vs/workbench/parts/debug/browser/debugActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugActions.ts @@ -388,6 +388,27 @@ export class PauseAction extends AbstractDebugAction { } } +export class TerminateThreadAction extends AbstractDebugAction { + static readonly ID = 'workbench.action.debug.terminateThread'; + static LABEL = nls.localize('terminateThread', "Terminate Thread"); + + constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { + super(id, label, undefined, debugService, keybindingService); + } + + public run(thread: IThread): TPromise { + if (!(thread instanceof Thread)) { + thread = this.debugService.getViewModel().focusedThread; + } + + return thread ? thread.terminate() : TPromise.as(null); + } + + protected isEnabled(state: State): boolean { + return super.isEnabled(state) && (state === State.Running || state === State.Stopped); + } +} + export class RestartFrameAction extends AbstractDebugAction { static readonly ID = 'workbench.action.debug.restartFrame'; static LABEL = nls.localize('restartFrame', "Restart Frame"); diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 5b177840f30..6477133f88a 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -123,6 +123,7 @@ export interface ISession { stepOut(args: DebugProtocol.StepOutArguments): TPromise; continue(args: DebugProtocol.ContinueArguments): TPromise; pause(args: DebugProtocol.PauseArguments): TPromise; + terminateThreads(args: DebugProtocol.TerminateThreadsArguments): TPromise; stepBack(args: DebugProtocol.StepBackArguments): TPromise; reverseContinue(args: DebugProtocol.ReverseContinueArguments): TPromise; @@ -199,6 +200,7 @@ export interface IThread extends ITreeElement { stepBack(): TPromise; continue(): TPromise; pause(): TPromise; + terminate(): TPromise; reverseContinue(): TPromise; } diff --git a/src/vs/workbench/parts/debug/common/debugModel.ts b/src/vs/workbench/parts/debug/common/debugModel.ts index 3007f9cafbf..f15a2b56c47 100644 --- a/src/vs/workbench/parts/debug/common/debugModel.ts +++ b/src/vs/workbench/parts/debug/common/debugModel.ts @@ -525,6 +525,10 @@ export class Thread implements IThread { return this.process.session.pause({ threadId: this.threadId }); } + public terminate(): TPromise { + return this.process.session.terminateThreads({ threadIds: [this.threadId] }); + } + public reverseContinue(): TPromise { return this.process.session.reverseContinue({ threadId: this.threadId }); } diff --git a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts index 8e3b75e7f39..6703b2b0c70 100644 --- a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts @@ -18,7 +18,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { BaseDebugController, twistiePixels, renderViewTree } from 'vs/workbench/parts/debug/browser/baseDebugView'; import { ITree, IActionProvider, IDataSource, IRenderer, IAccessibilityProvider } from 'vs/base/parts/tree/browser/tree'; import { IAction, IActionItem } from 'vs/base/common/actions'; -import { RestartAction, StopAction, ContinueAction, StepOverAction, StepIntoAction, StepOutAction, PauseAction, RestartFrameAction } from 'vs/workbench/parts/debug/browser/debugActions'; +import { RestartAction, StopAction, ContinueAction, StepOverAction, StepIntoAction, StepOutAction, PauseAction, RestartFrameAction, TerminateThreadAction } from 'vs/workbench/parts/debug/browser/debugActions'; import { CopyStackTraceAction } from 'vs/workbench/parts/debug/electron-browser/electronDebugActions'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -27,6 +27,7 @@ import { basenameOrAuthority } from 'vs/base/common/resources'; import { TreeResourceNavigator, WorkbenchTree } from 'vs/platform/list/browser/listService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; const $ = dom.$; @@ -268,6 +269,9 @@ class CallStackActionProvider implements IActionProvider { } else { actions.push(new PauseAction(PauseAction.ID, PauseAction.LABEL, this.debugService, this.keybindingService)); } + + actions.push(new Separator()); + actions.push(new TerminateThreadAction(TerminateThreadAction.ID, TerminateThreadAction.LABEL, this.debugService, this.keybindingService)); } else if (element instanceof StackFrame) { if (element.thread.process.session.capabilities.supportsRestartFrame) { actions.push(new RestartFrameAction(RestartFrameAction.ID, RestartFrameAction.LABEL, this.debugService, this.keybindingService)); diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index 2b6f3550af8..89cdf27b9b4 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -30,7 +30,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { DebugEditorModelManager } from 'vs/workbench/parts/debug/browser/debugEditorModelManager'; import { StepOverAction, ClearReplAction, FocusReplAction, StepIntoAction, StepOutAction, StartAction, RestartAction, ContinueAction, StopAction, DisconnectAction, PauseAction, AddFunctionBreakpointAction, - ConfigureAction, DisableAllBreakpointsAction, EnableAllBreakpointsAction, RemoveAllBreakpointsAction, RunAction, ReapplyBreakpointsAction, SelectAndStartAction + ConfigureAction, DisableAllBreakpointsAction, EnableAllBreakpointsAction, RemoveAllBreakpointsAction, RunAction, ReapplyBreakpointsAction, SelectAndStartAction, TerminateThreadAction } from 'vs/workbench/parts/debug/browser/debugActions'; import { DebugActionsWidget } from 'vs/workbench/parts/debug/browser/debugActionsWidget'; import * as service from 'vs/workbench/parts/debug/electron-browser/debugService'; @@ -134,6 +134,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(StopAction, StopAction registry.registerWorkbenchAction(new SyncActionDescriptor(DisconnectAction, DisconnectAction.ID, DisconnectAction.LABEL), 'Debug: Disconnect', debugCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ContinueAction, ContinueAction.ID, ContinueAction.LABEL, { primary: KeyCode.F5 }, CONTEXT_IN_DEBUG_MODE), 'Debug: Continue', debugCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(PauseAction, PauseAction.ID, PauseAction.LABEL, { primary: KeyCode.F6 }, CONTEXT_IN_DEBUG_MODE), 'Debug: Pause', debugCategory); +registry.registerWorkbenchAction(new SyncActionDescriptor(TerminateThreadAction, TerminateThreadAction.ID, TerminateThreadAction.LABEL, undefined, CONTEXT_IN_DEBUG_MODE), 'Debug: Terminate Thread', debugCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ConfigureAction, ConfigureAction.ID, ConfigureAction.LABEL), 'Debug: Open launch.json', debugCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(AddFunctionBreakpointAction, AddFunctionBreakpointAction.ID, AddFunctionBreakpointAction.LABEL), 'Debug: Add Function Breakpoint', debugCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ReapplyBreakpointsAction, ReapplyBreakpointsAction.ID, ReapplyBreakpointsAction.LABEL), 'Debug: Reapply All Breakpoints', debugCategory); diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index 80b235858b0..dd96720d946 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -350,6 +350,10 @@ export class RawDebugSession implements debug.ISession { return this.send('pause', args); } + public terminateThreads(args: DebugProtocol.TerminateThreadsArguments): TPromise { + return this.send('terminateThreads', args); + } + public setVariable(args: DebugProtocol.SetVariableArguments): TPromise { return this.send('setVariable', args); } diff --git a/src/vs/workbench/parts/debug/test/common/mockDebug.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts index e626309a642..6db8bef34f6 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -111,6 +111,7 @@ export class MockDebugService implements IDebugService { } export class MockSession implements ISession { + public readyForBreakpoints = true; public emittedStopped = true; @@ -217,6 +218,10 @@ export class MockSession implements ISession { return TPromise.as(null); } + public terminateThreads(args: DebugProtocol.TerminateThreadsArguments): TPromise { + return TPromise.as(null); + } + public setVariable(args: DebugProtocol.SetVariableArguments): TPromise { return TPromise.as(null); } -- GitLab