From 3697925e5bc0f9ab7332fbf89621bad41eea19ef Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 17 Dec 2020 16:39:29 +0100 Subject: [PATCH] Use menuService across all views for context menus. Breakpoints. fixes #112551 --- .../browser/breakpointEditorContribution.ts | 5 +- .../contrib/debug/browser/breakpointsView.ts | 283 +++++++++++++----- .../debug/browser/debug.contribution.ts | 38 +-- .../contrib/debug/browser/debugActions.ts | 120 -------- .../workbench/contrib/debug/common/debug.ts | 11 +- .../contrib/debug/common/debugViewModel.ts | 6 + 6 files changed, 234 insertions(+), 229 deletions(-) delete mode 100644 src/vs/workbench/contrib/debug/browser/debugActions.ts diff --git a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts index d2b337bfaa7..0effb45c4ba 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts @@ -15,7 +15,6 @@ import { IModelDecorationOptions, IModelDeltaDecoration, TrackedRangeStickiness, import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { RemoveBreakpointAction } from 'vs/workbench/contrib/debug/browser/debugActions'; import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, BreakpointWidgetContext, IBreakpointEditorContribution, IBreakpointUpdateData, IDebugConfiguration, State, IDebugSession } from 'vs/workbench/contrib/debug/common/debug'; import { IMarginData } from 'vs/editor/browser/controller/mouseTarget'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; @@ -301,7 +300,9 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi const actions: IAction[] = []; if (breakpoints.length === 1) { const breakpointType = breakpoints[0].logMessage ? nls.localize('logPoint', "Logpoint") : nls.localize('breakpoint', "Breakpoint"); - actions.push(new RemoveBreakpointAction(RemoveBreakpointAction.ID, nls.localize('removeBreakpoint', "Remove {0}", breakpointType), this.debugService)); + actions.push(new Action('debug.removeBreakpoint', nls.localize('removeBreakpoint', "Remove {0}", breakpointType), undefined, true, async () => { + await this.debugService.removeBreakpoints(breakpoints[0].getId()); + })); actions.push(new Action( 'workbench.debug.action.editBreakpointAction', nls.localize('editBreakpoint', "Edit {0}...", breakpointType), diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 0f125e52f7d..dd273f63015 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -5,10 +5,9 @@ import * as resources from 'vs/base/common/resources'; import * as dom from 'vs/base/browser/dom'; -import { IAction, Action, Separator } from 'vs/base/common/actions'; -import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINTS_FOCUSED, State, DEBUG_SCHEME, IFunctionBreakpoint, IExceptionBreakpoint, IEnablement, BREAKPOINT_EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution, IDebugModel, IDataBreakpoint, BREAKPOINTS_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug'; +import { IAction } from 'vs/base/common/actions'; +import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINTS_FOCUSED, State, DEBUG_SCHEME, IFunctionBreakpoint, IExceptionBreakpoint, IEnablement, IDebugModel, IDataBreakpoint, BREAKPOINTS_VIEW_ID, CONTEXT_BREAKPOINT_ITEM_TYPE, CONTEXT_EXCEPTION_BREAKPOINT_SUPPORTS_CONDITION, CONTEXT_BREAKPOINTS_EXIST, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_IN_DEBUG_MODE, IBaseBreakpoint, IBreakpointEditorContribution, BREAKPOINT_EDITOR_CONTRIBUTION_ID } from 'vs/workbench/contrib/debug/common/debug'; import { ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; -import { RemoveBreakpointAction, EnableAllBreakpointsAction, DisableAllBreakpointsAction, ReapplyBreakpointsAction } from 'vs/workbench/contrib/debug/browser/debugActions'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -23,12 +22,11 @@ import { KeyCode } from 'vs/base/common/keyCodes'; import { WorkbenchList, ListResourceNavigator } from 'vs/platform/list/browser/listService'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { attachInputBoxStyler } from 'vs/platform/theme/common/styler'; -import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane'; import { ILabelService } from 'vs/platform/label/common/label'; -import { IContextKeyService, ContextKeyEqualsExpr } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, ContextKeyEqualsExpr, IContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Gesture } from 'vs/base/browser/touch'; import { IViewDescriptorService } from 'vs/workbench/common/views'; import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor'; @@ -37,9 +35,11 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { Orientation } from 'vs/base/browser/ui/splitview/splitview'; import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; import * as icons from 'vs/workbench/contrib/debug/browser/debugIcons'; -import { registerAction2, Action2, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; +import { registerAction2, Action2, MenuId, IMenu, IMenuService } from 'vs/platform/actions/common/actions'; import { localize } from 'vs/nls'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; const $ = dom.$; @@ -64,6 +64,9 @@ export class BreakpointsView extends ViewPane { private list!: WorkbenchList; private needsRefresh = false; private ignoreLayout = false; + private menu: IMenu; + private breakpointItemType: IContextKey; + private exceptionBreakpointSupportsCondition: IContextKey; constructor( options: IViewletViewOptions, @@ -80,10 +83,21 @@ export class BreakpointsView extends ViewPane { @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, @ILabelService private readonly labelService: ILabelService, + @IMenuService menuService: IMenuService ) { super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); + this.menu = menuService.createMenu(MenuId.DebugBreakpointsContext, contextKeyService); + this._register(this.menu); + this.breakpointItemType = CONTEXT_BREAKPOINT_ITEM_TYPE.bindTo(contextKeyService); + this.exceptionBreakpointSupportsCondition = CONTEXT_EXCEPTION_BREAKPOINT_SUPPORTS_CONDITION.bindTo(contextKeyService); this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange())); + this._register(this.debugService.getViewModel().onDidSelectBreakpoint(breakpoint => { + if (breakpoint) { + // Only react when a new breakpoint is selected - to reduce refresh, since other times a refresh is not needed + this.onBreakpointsChange(); + } + })); } public renderBody(container: HTMLElement): void { @@ -140,7 +154,6 @@ export class BreakpointsView extends ViewPane { if (e.browserEvent instanceof MouseEvent && e.browserEvent.detail === 2 && e.element instanceof FunctionBreakpoint && e.element !== this.debugService.getViewModel().getSelectedBreakpoint()) { // double click this.debugService.getViewModel().setSelectedBreakpoint(e.element); - this.onBreakpointsChange(); } })); @@ -183,60 +196,20 @@ export class BreakpointsView extends ViewPane { } private onListContextMenu(e: IListContextMenuEvent): void { - if (!e.element) { - return; - } - - const actions: IAction[] = []; const element = e.element; + const type = element instanceof Breakpoint ? 'breakpoint' : element instanceof ExceptionBreakpoint ? 'exceptionBreakpoint' : + element instanceof FunctionBreakpoint ? 'functionBreakpoint' : element instanceof DataBreakpoint ? 'dataBreakpoint' : undefined; + this.breakpointItemType.set(type); + this.exceptionBreakpointSupportsCondition.set(element instanceof ExceptionBreakpoint && element.supportsCondition); - if (element instanceof ExceptionBreakpoint) { - if (element.supportsCondition) { - actions.push(new Action('workbench.action.debug.editExceptionBreakpointCondition', localize('editCondition', "Edit Condition"), '', true, async () => { - this.debugService.getViewModel().setSelectedBreakpoint(element); - this.onBreakpointsChange(); - })); - } - } else { - const breakpointType = element instanceof Breakpoint && element.logMessage ? localize('Logpoint', "Logpoint") : localize('Breakpoint', "Breakpoint"); - if (element instanceof Breakpoint || element instanceof FunctionBreakpoint) { - actions.push(new Action('workbench.action.debug.openEditorAndEditBreakpoint', localize('editBreakpoint', "Edit {0}...", breakpointType), '', true, async () => { - if (element instanceof Breakpoint) { - const editor = await openBreakpointSource(element, false, false, true, this.debugService, this.editorService); - if (editor) { - const codeEditor = editor.getControl(); - if (isCodeEditor(codeEditor)) { - codeEditor.getContribution(BREAKPOINT_EDITOR_CONTRIBUTION_ID).showBreakpointWidget(element.lineNumber, element.column); - } - } - } else { - this.debugService.getViewModel().setSelectedBreakpoint(element); - this.onBreakpointsChange(); - } - })); - actions.push(new Separator()); - } - - - actions.push(new RemoveBreakpointAction(RemoveBreakpointAction.ID, localize('removeBreakpoint', "Remove {0}", breakpointType), this.debugService)); - - if (this.debugService.getModel().getBreakpoints().length + this.debugService.getModel().getFunctionBreakpoints().length >= 1) { - actions.push(this.instantiationService.createInstance(MenuItemAction, removeAllBreakpointsCommand, undefined, {})); - actions.push(new Separator()); - - actions.push(new EnableAllBreakpointsAction(EnableAllBreakpointsAction.ID, EnableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); - actions.push(new DisableAllBreakpointsAction(DisableAllBreakpointsAction.ID, DisableAllBreakpointsAction.LABEL, this.debugService, this.keybindingService)); - } - - actions.push(new Separator()); - actions.push(new ReapplyBreakpointsAction(ReapplyBreakpointsAction.ID, ReapplyBreakpointsAction.LABEL, this.debugService, this.keybindingService)); - } + const actions: IAction[] = []; + const actionsDisposable = createAndFillInContextMenuActions(this.menu, { arg: e.element, shouldForwardArgs: false }, actions); this.contextMenuService.showContextMenu({ getAnchor: () => e.anchor, getActions: () => actions, getActionsContext: () => element, - onHide: () => dispose(actions) + onHide: () => dispose(actionsDisposable) }); } @@ -933,21 +906,60 @@ registerAction2(class extends Action2 { } }); -export const removeAllBreakpointsCommand = { - id: 'workbench.debug.viewlet.action.removeAllBreakpoints', - title: localize('removeAllBreakpoints', "Remove All Breakpoints"), - f1: true, - icon: icons.breakpointsRemoveAll, - menu: [{ - id: MenuId.ViewTitle, - group: 'navigation', - order: 30, - when: ContextKeyEqualsExpr.create('view', BREAKPOINTS_VIEW_ID) - }] -}; registerAction2(class extends Action2 { constructor() { - super(removeAllBreakpointsCommand); + super({ + id: 'workbench.debug.viewlet.action.removeBreakpoint', + title: localize('removeBreakpoint', "Remove Breakpoint"), + menu: [{ + id: MenuId.DebugBreakpointsContext, + group: '3_modification', + order: 10, + when: CONTEXT_BREAKPOINT_ITEM_TYPE.notEqualsTo('exceptionBreakpoint') + }] + }); + } + + async run(accessor: ServicesAccessor, breakpoint: IBaseBreakpoint): Promise { + const debugService = accessor.get(IDebugService); + if (breakpoint instanceof Breakpoint) { + await debugService.removeBreakpoints(breakpoint.getId()); + } else if (breakpoint instanceof FunctionBreakpoint) { + await debugService.removeFunctionBreakpoints(breakpoint.getId()); + } else if (breakpoint instanceof DataBreakpoint) { + await debugService.removeDataBreakpoints(breakpoint.getId()); + } + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.debug.viewlet.action.removeAllBreakpoints', + title: { + original: 'Remove All Breakpoints', + value: localize('removeAllBreakpoints', "Remove All Breakpoints"), + mnemonicedTitle: localize({ key: 'miRemoveAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Remove &&All Breakpoints") + }, + f1: true, + icon: icons.breakpointsRemoveAll, + menu: [{ + id: MenuId.ViewTitle, + group: 'navigation', + order: 30, + when: ContextKeyEqualsExpr.create('view', BREAKPOINTS_VIEW_ID) + }, { + id: MenuId.DebugBreakpointsContext, + group: '3_modification', + order: 20, + when: ContextKeyExpr.and(CONTEXT_BREAKPOINTS_EXIST, CONTEXT_BREAKPOINT_ITEM_TYPE.notEqualsTo('exceptionBreakpoint')) + }, { + id: MenuId.MenubarDebugMenu, + group: '5_breakpoints', + order: 3, + when: CONTEXT_DEBUGGERS_AVAILABLE + }] + }); } run(accessor: ServicesAccessor): void { @@ -957,3 +969,140 @@ registerAction2(class extends Action2 { debugService.removeDataBreakpoints(); } }); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.debug.viewlet.action.enableAllBreakpoints', + title: { + original: '', + value: localize('enableAllBreakpoints', "Enable All Breakpoints"), + mnemonicedTitle: localize({ key: 'miEnableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "&&Enable All Breakpoints"), + }, + f1: true, + precondition: CONTEXT_DEBUGGERS_AVAILABLE, + menu: [{ + id: MenuId.DebugBreakpointsContext, + group: 'z_commands', + order: 10, + when: ContextKeyExpr.and(CONTEXT_BREAKPOINTS_EXIST, CONTEXT_BREAKPOINT_ITEM_TYPE.notEqualsTo('exceptionBreakpoint')) + }, { + id: MenuId.MenubarDebugMenu, + group: '5_breakpoints', + order: 1, + when: CONTEXT_DEBUGGERS_AVAILABLE + }] + }); + } + + async run(accessor: ServicesAccessor): Promise { + const debugService = accessor.get(IDebugService); + await debugService.enableOrDisableBreakpoints(true); + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.debug.viewlet.action.disableAllBreakpoints', + title: { + original: 'Disable All Breakpoints', + value: localize('disableAllBreakpoints', "Disable All Breakpoints"), + mnemonicedTitle: localize({ key: 'miDisableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Disable A&&ll Breakpoints") + }, + f1: true, + precondition: CONTEXT_DEBUGGERS_AVAILABLE, + menu: [{ + id: MenuId.DebugBreakpointsContext, + group: 'z_commands', + order: 20, + when: ContextKeyExpr.and(CONTEXT_BREAKPOINTS_EXIST, CONTEXT_BREAKPOINT_ITEM_TYPE.notEqualsTo('exceptionBreakpoint')) + }, { + id: MenuId.MenubarDebugMenu, + group: '5_breakpoints', + order: 2, + + when: CONTEXT_DEBUGGERS_AVAILABLE + }] + }); + } + + async run(accessor: ServicesAccessor): Promise { + const debugService = accessor.get(IDebugService); + await debugService.enableOrDisableBreakpoints(false); + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.debug.viewlet.action.reapplyBreakpointsAction', + title: localize('reapplyAllBreakpoints', "Reapply All Breakpoints"), + f1: true, + precondition: CONTEXT_IN_DEBUG_MODE, + menu: [{ + id: MenuId.DebugBreakpointsContext, + group: 'z_commands', + order: 30, + when: ContextKeyExpr.and(CONTEXT_BREAKPOINTS_EXIST, CONTEXT_BREAKPOINT_ITEM_TYPE.notEqualsTo('exceptionBreakpoint')) + }] + }); + } + + async run(accessor: ServicesAccessor): Promise { + const debugService = accessor.get(IDebugService); + await debugService.setBreakpointsActivated(true); + } +}); + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'workbench.action.debug.editExceptionBreakpointCondition', + title: localize('editCondition', "Edit Condition"), + menu: [{ + id: MenuId.DebugBreakpointsContext, + group: 'navigation', + order: 10, + when: CONTEXT_EXCEPTION_BREAKPOINT_SUPPORTS_CONDITION + }] + }); + } + + async run(accessor: ServicesAccessor, breakpoint: ExceptionBreakpoint): Promise { + const debugService = accessor.get(IDebugService); + debugService.getViewModel().setSelectedBreakpoint(breakpoint); + } +}); + + +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'debug.editBreakpoint', + title: localize('editBreakpoint', "Edit Breakpoint..."), + menu: [{ + id: MenuId.DebugBreakpointsContext, + group: 'navigation', + order: 10, + when: ContextKeyExpr.or(CONTEXT_BREAKPOINT_ITEM_TYPE.isEqualTo('breakpoint'), CONTEXT_BREAKPOINT_ITEM_TYPE.isEqualTo('functionBreakpoint')) + }] + }); + } + + async run(accessor: ServicesAccessor, breakpoint: ExceptionBreakpoint): Promise { + const debugService = accessor.get(IDebugService); + const editorService = accessor.get(IEditorService); + if (breakpoint instanceof Breakpoint) { + const editor = await openBreakpointSource(breakpoint, false, false, true, debugService, editorService); + if (editor) { + const codeEditor = editor.getControl(); + if (isCodeEditor(codeEditor)) { + codeEditor.getContribution(BREAKPOINT_EDITOR_CONTRIBUTION_ID).showBreakpointWidget(breakpoint.lineNumber, breakpoint.column); + } + } + } else { + debugService.getViewModel().setSelectedBreakpoint(breakpoint); + } + } +}); diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 6b6b2944a8f..02dd2427cf3 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -12,14 +12,13 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkbenchActionRegistry, Extensions as WorkbenchActionRegistryExtensions, CATEGORIES } from 'vs/workbench/common/actions'; -import { BreakpointsView, removeAllBreakpointsCommand, FUNCTION_BREAKPOINT_COMMAND_ID } from 'vs/workbench/contrib/debug/browser/breakpointsView'; +import { BreakpointsView, FUNCTION_BREAKPOINT_COMMAND_ID } from 'vs/workbench/contrib/debug/browser/breakpointsView'; import { CallStackView } from 'vs/workbench/contrib/debug/browser/callStackView'; import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import { IDebugService, VIEWLET_ID, DEBUG_PANEL_ID, CONTEXT_IN_DEBUG_MODE, INTERNAL_CONSOLE_OPTIONS_SCHEMA, CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID, LOADED_SCRIPTS_VIEW_ID, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_DEBUG_UX, BREAKPOINT_EDITOR_CONTRIBUTION_ID, REPL_VIEW_ID, CONTEXT_BREAKPOINTS_EXIST, EDITOR_CONTRIBUTION_ID, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_SET_VARIABLE_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_VARIABLE_EVALUATE_NAME_PRESENT, getStateLabel, State, CONTEXT_WATCH_ITEM_TYPE, } from 'vs/workbench/contrib/debug/common/debug'; -import { DisableAllBreakpointsAction, EnableAllBreakpointsAction, ReapplyBreakpointsAction } from 'vs/workbench/contrib/debug/browser/debugActions'; import { DebugToolBar } from 'vs/workbench/contrib/debug/browser/debugToolBar'; import { DebugService } from 'vs/workbench/contrib/debug/browser/debugService'; import { registerCommands, ADD_CONFIGURATION_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_STACK_TRACE_ID, RESTART_SESSION_ID, TERMINATE_THREAD_ID, STEP_OVER_ID, STEP_INTO_ID, STEP_OUT_ID, PAUSE_ID, DISCONNECT_ID, STOP_ID, RESTART_FRAME_ID, CONTINUE_ID, FOCUS_REPL_ID, JUMP_TO_CURSOR_ID, RESTART_LABEL, STEP_INTO_LABEL, STEP_OVER_LABEL, STEP_OUT_LABEL, PAUSE_LABEL, DISCONNECT_LABEL, STOP_LABEL, CONTINUE_LABEL, DEBUG_CONFIGURE_COMMAND_ID, DEBUG_START_LABEL, DEBUG_START_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_RUN_COMMAND_ID, EDIT_EXPRESSION_COMMAND_ID, REMOVE_EXPRESSION_COMMAND_ID } from 'vs/workbench/contrib/debug/browser/debugCommands'; @@ -98,10 +97,6 @@ function regsiterEditorContributions(): void { function registerCommandsAndActions(): void { - registry.registerWorkbenchAction(SyncActionDescriptor.from(ReapplyBreakpointsAction), 'Debug: Reapply All Breakpoints', debugCategory, CONTEXT_DEBUGGERS_AVAILABLE); - registry.registerWorkbenchAction(SyncActionDescriptor.from(EnableAllBreakpointsAction), 'Debug: Enable All Breakpoints', debugCategory, CONTEXT_DEBUGGERS_AVAILABLE); - registry.registerWorkbenchAction(SyncActionDescriptor.from(DisableAllBreakpointsAction), 'Debug: Disable All Breakpoints', debugCategory, CONTEXT_DEBUGGERS_AVAILABLE); - const registerDebugCommandPaletteItem = (id: string, title: string, when?: ContextKeyExpression, precondition?: ContextKeyExpression) => { MenuRegistry.appendMenuItem(MenuId.CommandPalette, { when: ContextKeyExpr.and(CONTEXT_DEBUGGERS_AVAILABLE, when), @@ -385,36 +380,7 @@ function registerDebugMenu(): void { when: CONTEXT_DEBUGGERS_AVAILABLE }); - // Modify Breakpoints - MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { - group: '5_breakpoints', - command: { - id: EnableAllBreakpointsAction.ID, - title: nls.localize({ key: 'miEnableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "&&Enable All Breakpoints") - }, - order: 1, - when: CONTEXT_DEBUGGERS_AVAILABLE - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { - group: '5_breakpoints', - command: { - id: DisableAllBreakpointsAction.ID, - title: nls.localize({ key: 'miDisableAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Disable A&&ll Breakpoints") - }, - order: 2, - when: CONTEXT_DEBUGGERS_AVAILABLE - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { - group: '5_breakpoints', - command: { - id: removeAllBreakpointsCommand.id, - title: nls.localize({ key: 'miRemoveAllBreakpoints', comment: ['&& denotes a mnemonic'] }, "Remove &&All Breakpoints") - }, - order: 3, - when: CONTEXT_DEBUGGERS_AVAILABLE - }); + // Breakpoint actions are registered from breakpointsView.ts // Install Debuggers MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, { diff --git a/src/vs/workbench/contrib/debug/browser/debugActions.ts b/src/vs/workbench/contrib/debug/browser/debugActions.ts deleted file mode 100644 index eeb2a195164..00000000000 --- a/src/vs/workbench/contrib/debug/browser/debugActions.ts +++ /dev/null @@ -1,120 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as nls from 'vs/nls'; -import { Action } from 'vs/base/common/actions'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IDebugService, State, IEnablement, IBreakpoint } from 'vs/workbench/contrib/debug/common/debug'; -import { Breakpoint, FunctionBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; - -export abstract class AbstractDebugAction extends Action { - - constructor( - id: string, label: string, cssClass: string, - @IDebugService protected debugService: IDebugService, - @IKeybindingService protected keybindingService: IKeybindingService, - ) { - super(id, label, cssClass, false); - this._register(this.debugService.onDidChangeState(state => this.updateEnablement(state))); - - this.updateLabel(label); - this.updateEnablement(); - } - - run(_: any): Promise { - throw new Error('implement me'); - } - - get tooltip(): string { - const keybinding = this.keybindingService.lookupKeybinding(this.id); - const keybindingLabel = keybinding && keybinding.getLabel(); - - return keybindingLabel ? `${this.label} (${keybindingLabel})` : this.label; - } - - protected updateLabel(newLabel: string): void { - this.label = newLabel; - } - - protected updateEnablement(state = this.debugService.state): void { - this.enabled = this.isEnabled(state); - } - - protected isEnabled(_: State): boolean { - return true; - } -} - -export class RemoveBreakpointAction extends Action { - static readonly ID = 'workbench.debug.viewlet.action.removeBreakpoint'; - static readonly LABEL = nls.localize('removeBreakpoint', "Remove Breakpoint"); - - constructor(id: string, label: string, @IDebugService private readonly debugService: IDebugService) { - super(id, label, 'debug-action remove'); - } - - run(breakpoint: IBreakpoint): Promise { - return breakpoint instanceof Breakpoint ? this.debugService.removeBreakpoints(breakpoint.getId()) - : breakpoint instanceof FunctionBreakpoint ? this.debugService.removeFunctionBreakpoints(breakpoint.getId()) : this.debugService.removeDataBreakpoints(breakpoint.getId()); - } -} - -export class EnableAllBreakpointsAction extends AbstractDebugAction { - static readonly ID = 'workbench.debug.viewlet.action.enableAllBreakpoints'; - static readonly LABEL = nls.localize('enableAllBreakpoints', "Enable All Breakpoints"); - - constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { - super(id, label, 'debug-action enable-all-breakpoints', debugService, keybindingService); - this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); - } - - run(): Promise { - return this.debugService.enableOrDisableBreakpoints(true); - } - - protected isEnabled(_: State): boolean { - const model = this.debugService.getModel(); - return (>model.getBreakpoints()).concat(model.getFunctionBreakpoints()).concat(model.getExceptionBreakpoints()).some(bp => !bp.enabled); - } -} - -export class DisableAllBreakpointsAction extends AbstractDebugAction { - static readonly ID = 'workbench.debug.viewlet.action.disableAllBreakpoints'; - static readonly LABEL = nls.localize('disableAllBreakpoints', "Disable All Breakpoints"); - - constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { - super(id, label, 'debug-action disable-all-breakpoints', debugService, keybindingService); - this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); - } - - run(): Promise { - return this.debugService.enableOrDisableBreakpoints(false); - } - - protected isEnabled(_: State): boolean { - const model = this.debugService.getModel(); - return (>model.getBreakpoints()).concat(model.getFunctionBreakpoints()).concat(model.getExceptionBreakpoints()).some(bp => bp.enabled); - } -} - -export class ReapplyBreakpointsAction extends AbstractDebugAction { - static readonly ID = 'workbench.debug.viewlet.action.reapplyBreakpointsAction'; - static readonly LABEL = nls.localize('reapplyAllBreakpoints', "Reapply All Breakpoints"); - - constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { - super(id, label, '', debugService, keybindingService); - this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.updateEnablement())); - } - - run(): Promise { - return this.debugService.setBreakpointsActivated(true); - } - - protected isEnabled(state: State): boolean { - const model = this.debugService.getModel(); - return (state === State.Running || state === State.Stopped) && - ((model.getFunctionBreakpoints().length + model.getBreakpoints().length + model.getExceptionBreakpoints().length + model.getDataBreakpoints().length) > 0); - } -} diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index b19c0e480d2..3a9b36fb18e 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -45,14 +45,16 @@ export const CONTEXT_IN_DEBUG_MODE = new RawContextKey('inDebugMode', f export const CONTEXT_IN_DEBUG_REPL = new RawContextKey('inDebugRepl', false); export const CONTEXT_BREAKPOINT_WIDGET_VISIBLE = new RawContextKey('breakpointWidgetVisible', false); export const CONTEXT_IN_BREAKPOINT_WIDGET = new RawContextKey('inBreakpointWidget', false); -export const CONTEXT_BREAKPOINTS_FOCUSED = new RawContextKey('breakpointsFocused', true); -export const CONTEXT_WATCH_EXPRESSIONS_FOCUSED = new RawContextKey('watchExpressionsFocused', true); -export const CONTEXT_WATCH_EXPRESSIONS_EXIST = new RawContextKey('watchExpressionsExist', true); -export const CONTEXT_VARIABLES_FOCUSED = new RawContextKey('variablesFocused', true); +export const CONTEXT_BREAKPOINTS_FOCUSED = new RawContextKey('breakpointsFocused', false); +export const CONTEXT_WATCH_EXPRESSIONS_FOCUSED = new RawContextKey('watchExpressionsFocused', false); +export const CONTEXT_WATCH_EXPRESSIONS_EXIST = new RawContextKey('watchExpressionsExist', false); +export const CONTEXT_VARIABLES_FOCUSED = new RawContextKey('variablesFocused', false); export const CONTEXT_EXPRESSION_SELECTED = new RawContextKey('expressionSelected', false); export const CONTEXT_BREAKPOINT_SELECTED = new RawContextKey('breakpointSelected', false); export const CONTEXT_CALLSTACK_ITEM_TYPE = new RawContextKey('callStackItemType', undefined); export const CONTEXT_WATCH_ITEM_TYPE = new RawContextKey('watchItemType', undefined); +export const CONTEXT_BREAKPOINT_ITEM_TYPE = new RawContextKey('breakpointItemType', undefined); +export const CONTEXT_EXCEPTION_BREAKPOINT_SUPPORTS_CONDITION = new RawContextKey('exceptionBreakpointSupportsCondition', false); export const CONTEXT_LOADED_SCRIPTS_SUPPORTED = new RawContextKey('loadedScriptsSupported', false); export const CONTEXT_LOADED_SCRIPTS_ITEM_TYPE = new RawContextKey('loadedScriptsItemType', undefined); export const CONTEXT_FOCUSED_SESSION_IS_ATTACH = new RawContextKey('focusedSessionIsAttach', false); @@ -451,6 +453,7 @@ export interface IViewModel extends ITreeElement { onDidFocusSession: Event; onDidFocusStackFrame: Event<{ stackFrame: IStackFrame | undefined, explicit: boolean }>; onDidSelectExpression: Event; + onDidSelectBreakpoint: Event; onWillUpdateViews: Event; } diff --git a/src/vs/workbench/contrib/debug/common/debugViewModel.ts b/src/vs/workbench/contrib/debug/common/debugViewModel.ts index 3ff9f675cc5..95edb422d4d 100644 --- a/src/vs/workbench/contrib/debug/common/debugViewModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugViewModel.ts @@ -20,6 +20,7 @@ export class ViewModel implements IViewModel { private readonly _onDidFocusSession = new Emitter(); private readonly _onDidFocusStackFrame = new Emitter<{ stackFrame: IStackFrame | undefined, explicit: boolean }>(); private readonly _onDidSelectExpression = new Emitter(); + private readonly _onDidSelectBreakpoint = new Emitter(); private readonly _onWillUpdateViews = new Emitter(); private expressionSelectedContextKey!: IContextKey; private breakpointSelectedContextKey!: IContextKey; @@ -112,6 +113,10 @@ export class ViewModel implements IViewModel { return this._onDidSelectExpression.event; } + get onDidSelectBreakpoint(): Event { + return this._onDidSelectBreakpoint.event; + } + getSelectedBreakpoint(): IFunctionBreakpoint | IExceptionBreakpoint | undefined { return this.selectedBreakpoint; } @@ -127,6 +132,7 @@ export class ViewModel implements IViewModel { setSelectedBreakpoint(breakpoint: IFunctionBreakpoint | IExceptionBreakpoint | undefined): void { this.selectedBreakpoint = breakpoint; this.breakpointSelectedContextKey.set(!!breakpoint); + this._onDidSelectBreakpoint.fire(breakpoint); } isMultiSessionView(): boolean { -- GitLab