Skip to content

Commit 1fe13cd

Browse files
authored
Merge pull request microsoft#258357 from microsoft/connor4312/237751
Add debug/watch/context to menus
2 parents 6dcb644 + 1a72f8a commit 1fe13cd

File tree

7 files changed

+152
-62
lines changed

7 files changed

+152
-62
lines changed

src/vs/workbench/contrib/debug/browser/debug.contribution.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { BreakpointsView } from './breakpointsView.js';
4040
import { CallStackEditorContribution } from './callStackEditorContribution.js';
4141
import { CallStackView } from './callStackView.js';
4242
import { registerColors } from './debugColors.js';
43-
import { ADD_CONFIGURATION_ID, ADD_TO_WATCH_ID, ADD_TO_WATCH_LABEL, CALLSTACK_BOTTOM_ID, CALLSTACK_BOTTOM_LABEL, CALLSTACK_DOWN_ID, CALLSTACK_DOWN_LABEL, CALLSTACK_TOP_ID, CALLSTACK_TOP_LABEL, CALLSTACK_UP_ID, CALLSTACK_UP_LABEL, CONTINUE_ID, CONTINUE_LABEL, COPY_EVALUATE_PATH_ID, COPY_EVALUATE_PATH_LABEL, COPY_STACK_TRACE_ID, COPY_VALUE_ID, COPY_VALUE_LABEL, DEBUG_COMMAND_CATEGORY, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_RUN_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_START_COMMAND_ID, DEBUG_START_LABEL, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, DISCONNECT_ID, DISCONNECT_LABEL, EDIT_EXPRESSION_COMMAND_ID, JUMP_TO_CURSOR_ID, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, PAUSE_ID, PAUSE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, REMOVE_EXPRESSION_COMMAND_ID, RESTART_FRAME_ID, RESTART_LABEL, RESTART_SESSION_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, SELECT_DEBUG_SESSION_ID, SELECT_DEBUG_SESSION_LABEL, SET_EXPRESSION_COMMAND_ID, SHOW_LOADED_SCRIPTS_ID, STEP_INTO_ID, STEP_INTO_LABEL, STEP_INTO_TARGET_ID, STEP_INTO_TARGET_LABEL, STEP_OUT_ID, STEP_OUT_LABEL, STEP_OVER_ID, STEP_OVER_LABEL, STOP_ID, STOP_LABEL, TERMINATE_THREAD_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_ADDRESS_ID, COPY_ADDRESS_LABEL, TOGGLE_BREAKPOINT_ID } from './debugCommands.js';
43+
import { ADD_CONFIGURATION_ID, ADD_TO_WATCH_ID, ADD_TO_WATCH_LABEL, CALLSTACK_BOTTOM_ID, CALLSTACK_BOTTOM_LABEL, CALLSTACK_DOWN_ID, CALLSTACK_DOWN_LABEL, CALLSTACK_TOP_ID, CALLSTACK_TOP_LABEL, CALLSTACK_UP_ID, CALLSTACK_UP_LABEL, CONTINUE_ID, CONTINUE_LABEL, COPY_EVALUATE_PATH_ID, COPY_EVALUATE_PATH_LABEL, COPY_STACK_TRACE_ID, COPY_VALUE_ID, COPY_VALUE_LABEL, DEBUG_COMMAND_CATEGORY, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_RUN_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_START_COMMAND_ID, DEBUG_START_LABEL, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, DISCONNECT_ID, DISCONNECT_LABEL, EDIT_EXPRESSION_COMMAND_ID, JUMP_TO_CURSOR_ID, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, PAUSE_ID, PAUSE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, REMOVE_EXPRESSION_COMMAND_ID, RESTART_FRAME_ID, RESTART_LABEL, RESTART_SESSION_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, SELECT_DEBUG_SESSION_ID, SELECT_DEBUG_SESSION_LABEL, SET_EXPRESSION_COMMAND_ID, SHOW_LOADED_SCRIPTS_ID, STEP_INTO_ID, STEP_INTO_LABEL, STEP_INTO_TARGET_ID, STEP_INTO_TARGET_LABEL, STEP_OUT_ID, STEP_OUT_LABEL, STEP_OVER_ID, STEP_OVER_LABEL, STOP_ID, STOP_LABEL, TERMINATE_THREAD_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_ADDRESS_ID, COPY_ADDRESS_LABEL, TOGGLE_BREAKPOINT_ID, BREAK_WHEN_VALUE_CHANGES_ID, BREAK_WHEN_VALUE_IS_ACCESSED_ID, BREAK_WHEN_VALUE_IS_READ_ID } from './debugCommands.js';
4444
import { DebugConsoleQuickAccess } from './debugConsoleQuickAccess.js';
4545
import { RunToCursorAction, SelectionToReplAction, SelectionToWatchExpressionsAction } from './debugEditorActions.js';
4646
import { DebugEditorContribution } from './debugEditorContribution.js';
@@ -62,7 +62,7 @@ import { ReplAccessibilityHelp } from './replAccessibilityHelp.js';
6262
import { ReplAccessibleView } from './replAccessibleView.js';
6363
import { RunAndDebugAccessibilityHelp } from './runAndDebugAccessibilityHelp.js';
6464
import { StatusBarColorProvider } from './statusbarColorProvider.js';
65-
import { BREAK_WHEN_VALUE_CHANGES_ID, BREAK_WHEN_VALUE_IS_ACCESSED_ID, BREAK_WHEN_VALUE_IS_READ_ID, SET_VARIABLE_ID, VIEW_MEMORY_ID, VariablesView } from './variablesView.js';
65+
import { SET_VARIABLE_ID, VIEW_MEMORY_ID, VariablesView } from './variablesView.js';
6666
import { ADD_WATCH_ID, ADD_WATCH_LABEL, REMOVE_WATCH_EXPRESSIONS_COMMAND_ID, REMOVE_WATCH_EXPRESSIONS_LABEL, WatchExpressionsView } from './watchExpressionsView.js';
6767
import { WelcomeView } from './welcomeView.js';
6868

@@ -204,6 +204,9 @@ registerDebugViewMenuItem(MenuId.DebugWatchContext, COPY_VALUE_ID, nls.localize(
204204
registerDebugViewMenuItem(MenuId.DebugWatchContext, VIEW_MEMORY_ID, nls.localize('viewMemory', "View Binary Data"), 10, CONTEXT_CAN_VIEW_MEMORY, undefined, 'inline', icons.debugInspectMemory);
205205
registerDebugViewMenuItem(MenuId.DebugWatchContext, REMOVE_EXPRESSION_COMMAND_ID, nls.localize('removeWatchExpression', "Remove Expression"), 20, CONTEXT_WATCH_ITEM_TYPE.isEqualTo('expression'), undefined, 'inline', icons.watchExpressionRemove);
206206
registerDebugViewMenuItem(MenuId.DebugWatchContext, REMOVE_WATCH_EXPRESSIONS_COMMAND_ID, REMOVE_WATCH_EXPRESSIONS_LABEL, 20, undefined, undefined, 'z_commands');
207+
registerDebugViewMenuItem(MenuId.DebugWatchContext, BREAK_WHEN_VALUE_IS_READ_ID, nls.localize('breakWhenValueIsRead', "Break on Value Read"), 200, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, undefined, 'z_commands');
208+
registerDebugViewMenuItem(MenuId.DebugWatchContext, BREAK_WHEN_VALUE_CHANGES_ID, nls.localize('breakWhenValueChanges', "Break on Value Change"), 210, CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, undefined, 'z_commands');
209+
registerDebugViewMenuItem(MenuId.DebugWatchContext, BREAK_WHEN_VALUE_IS_ACCESSED_ID, nls.localize('breakWhenValueIsAccessed', "Break on Value Access"), 220, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, undefined, 'z_commands');
207210

208211
registerDebugViewMenuItem(MenuId.NotebookVariablesContext, COPY_NOTEBOOK_VARIABLE_VALUE_ID, COPY_NOTEBOOK_VARIABLE_VALUE_LABEL, 20, CONTEXT_VARIABLE_VALUE);
209212

src/vs/workbench/contrib/debug/browser/debugCommands.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';
88
import { List } from '../../../../base/browser/ui/list/listWidget.js';
99
import { KeybindingsRegistry, KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
1010
import { IListService } from '../../../../platform/list/browser/listService.js';
11-
import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_EXPRESSION_SELECTED, IConfig, IStackFrame, IThread, IDebugSession, CONTEXT_DEBUG_STATE, IDebugConfiguration, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, REPL_VIEW_ID, CONTEXT_DEBUGGERS_AVAILABLE, State, getStateLabel, CONTEXT_BREAKPOINT_INPUT_FOCUSED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, VIEWLET_ID, CONTEXT_DISASSEMBLY_VIEW_FOCUS, CONTEXT_IN_DEBUG_REPL, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, isFrameDeemphasized } from '../common/debug.js';
11+
import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_EXPRESSION_SELECTED, IConfig, IStackFrame, IThread, IDebugSession, CONTEXT_DEBUG_STATE, IDebugConfiguration, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, REPL_VIEW_ID, CONTEXT_DEBUGGERS_AVAILABLE, State, getStateLabel, CONTEXT_BREAKPOINT_INPUT_FOCUSED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, VIEWLET_ID, CONTEXT_DISASSEMBLY_VIEW_FOCUS, CONTEXT_IN_DEBUG_REPL, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, isFrameDeemphasized, IDataBreakpointInfoResponse, DataBreakpointSetType } from '../common/debug.js';
1212
import { Expression, Variable, Breakpoint, FunctionBreakpoint, DataBreakpoint, Thread } from '../common/debugModel.js';
1313
import { IExtensionsWorkbenchService } from '../../extensions/common/extensions.js';
1414
import { ICodeEditor, isCodeEditor } from '../../../../editor/browser/editorBrowser.js';
@@ -81,6 +81,9 @@ export const CALLSTACK_DOWN_ID = 'workbench.action.debug.callStackDown';
8181
export const ADD_TO_WATCH_ID = 'debug.addToWatchExpressions';
8282
export const COPY_EVALUATE_PATH_ID = 'debug.copyEvaluatePath';
8383
export const COPY_VALUE_ID = 'workbench.debug.viewlet.action.copyValue';
84+
export const BREAK_WHEN_VALUE_CHANGES_ID = 'debug.breakWhenValueChanges';
85+
export const BREAK_WHEN_VALUE_IS_ACCESSED_ID = 'debug.breakWhenValueIsAccessed';
86+
export const BREAK_WHEN_VALUE_IS_READ_ID = 'debug.breakWhenValueIsRead';
8487

8588
export const DEBUG_COMMAND_CATEGORY: ILocalizedString = nls.localize2('debug', 'Debug');
8689
export const RESTART_LABEL = nls.localize2('restartDebug', "Restart");
@@ -116,6 +119,12 @@ export const SELECT_DEBUG_SESSION_LABEL = nls.localize2('selectDebugSession', "S
116119
export const DEBUG_QUICK_ACCESS_PREFIX = 'debug ';
117120
export const DEBUG_CONSOLE_QUICK_ACCESS_PREFIX = 'debug consoles ';
118121

122+
let dataBreakpointInfoResponse: IDataBreakpointInfoResponse | undefined;
123+
124+
export function setDataBreakpointInfoResponse(resp: IDataBreakpointInfoResponse | undefined) {
125+
dataBreakpointInfoResponse = resp;
126+
}
127+
119128
interface CallStackContext {
120129
sessionId: string;
121130
threadId: string;
@@ -902,6 +911,36 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
902911
}
903912
});
904913

914+
CommandsRegistry.registerCommand({
915+
id: BREAK_WHEN_VALUE_CHANGES_ID,
916+
handler: async (accessor: ServicesAccessor) => {
917+
const debugService = accessor.get(IDebugService);
918+
if (dataBreakpointInfoResponse) {
919+
await debugService.addDataBreakpoint({ description: dataBreakpointInfoResponse.description, src: { type: DataBreakpointSetType.Variable, dataId: dataBreakpointInfoResponse.dataId! }, canPersist: !!dataBreakpointInfoResponse.canPersist, accessTypes: dataBreakpointInfoResponse.accessTypes, accessType: 'write' });
920+
}
921+
}
922+
});
923+
924+
CommandsRegistry.registerCommand({
925+
id: BREAK_WHEN_VALUE_IS_ACCESSED_ID,
926+
handler: async (accessor: ServicesAccessor) => {
927+
const debugService = accessor.get(IDebugService);
928+
if (dataBreakpointInfoResponse) {
929+
await debugService.addDataBreakpoint({ description: dataBreakpointInfoResponse.description, src: { type: DataBreakpointSetType.Variable, dataId: dataBreakpointInfoResponse.dataId! }, canPersist: !!dataBreakpointInfoResponse.canPersist, accessTypes: dataBreakpointInfoResponse.accessTypes, accessType: 'readWrite' });
930+
}
931+
}
932+
});
933+
934+
CommandsRegistry.registerCommand({
935+
id: BREAK_WHEN_VALUE_IS_READ_ID,
936+
handler: async (accessor: ServicesAccessor) => {
937+
const debugService = accessor.get(IDebugService);
938+
if (dataBreakpointInfoResponse) {
939+
await debugService.addDataBreakpoint({ description: dataBreakpointInfoResponse.description, src: { type: DataBreakpointSetType.Variable, dataId: dataBreakpointInfoResponse.dataId! }, canPersist: !!dataBreakpointInfoResponse.canPersist, accessTypes: dataBreakpointInfoResponse.accessTypes, accessType: 'read' });
940+
}
941+
}
942+
});
943+
905944
KeybindingsRegistry.registerCommandAndKeybindingRule({
906945
id: 'debug.removeBreakpoint',
907946
weight: KeybindingWeight.WorkbenchContrib,

src/vs/workbench/contrib/debug/browser/variablesView.ts

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,18 @@ import { IEditorService, SIDE_GROUP } from '../../../services/editor/common/edit
4242
import { IExtensionService } from '../../../services/extensions/common/extensions.js';
4343
import { IViewsService } from '../../../services/views/common/viewsService.js';
4444
import { IExtensionsWorkbenchService } from '../../extensions/common/extensions.js';
45-
import { CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, CONTEXT_VARIABLES_FOCUSED, DataBreakpointSetType, DebugVisualizationType, IDataBreakpointInfoResponse, IDebugService, IDebugViewWithVariables, IExpression, IScope, IStackFrame, IViewModel, VARIABLES_VIEW_ID, WATCH_VIEW_ID } from '../common/debug.js';
45+
import { CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, CONTEXT_VARIABLES_FOCUSED, DebugVisualizationType, IDebugService, IDebugViewWithVariables, IExpression, IScope, IStackFrame, IViewModel, VARIABLES_VIEW_ID, WATCH_VIEW_ID } from '../common/debug.js';
4646
import { getContextForVariable } from '../common/debugContext.js';
4747
import { ErrorScope, Expression, Scope, StackFrame, Variable, VisualizedExpression, getUriForDebugMemory } from '../common/debugModel.js';
4848
import { DebugVisualizer, IDebugVisualizerService } from '../common/debugVisualizers.js';
4949
import { AbstractExpressionDataSource, AbstractExpressionsRenderer, expressionAndScopeLabelProvider, IExpressionTemplateData, IInputBoxOptions, renderViewTree } from './baseDebugView.js';
50-
import { ADD_TO_WATCH_ID, ADD_TO_WATCH_LABEL, COPY_EVALUATE_PATH_ID, COPY_EVALUATE_PATH_LABEL, COPY_VALUE_ID, COPY_VALUE_LABEL } from './debugCommands.js';
50+
import { ADD_TO_WATCH_ID, ADD_TO_WATCH_LABEL, COPY_EVALUATE_PATH_ID, COPY_EVALUATE_PATH_LABEL, COPY_VALUE_ID, COPY_VALUE_LABEL, setDataBreakpointInfoResponse } from './debugCommands.js';
5151
import { DebugExpressionRenderer } from './debugExpressionRenderer.js';
5252

5353
const $ = dom.$;
5454
let forgetScopes = true;
5555

5656
let variableInternalContext: Variable | undefined;
57-
let dataBreakpointInfoResponse: IDataBreakpointInfoResponse | undefined;
5857

5958
interface IVariablesContext {
6059
sessionId: string | undefined;
@@ -279,9 +278,10 @@ async function getContextForVariableMenuWithDataAccess(parentContext: IContextKe
279278
}
280279

281280
const contextKeys: [string, unknown][] = [];
282-
dataBreakpointInfoResponse = await session.dataBreakpointInfo(variable.name, variable.parent.reference);
281+
const dataBreakpointInfoResponse = await session.dataBreakpointInfo(variable.name, variable.parent.reference);
283282
const dataBreakpointId = dataBreakpointInfoResponse?.dataId;
284283
const dataBreakpointAccessTypes = dataBreakpointInfoResponse?.accessTypes;
284+
setDataBreakpointInfoResponse(dataBreakpointInfoResponse);
285285

286286
if (!dataBreakpointAccessTypes) {
287287
contextKeys.push([CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED.key, !!dataBreakpointId]);
@@ -786,39 +786,6 @@ async function tryInstallHexEditor(extensionsWorkbenchService: IExtensionsWorkbe
786786
}
787787
}
788788

789-
export const BREAK_WHEN_VALUE_CHANGES_ID = 'debug.breakWhenValueChanges';
790-
CommandsRegistry.registerCommand({
791-
id: BREAK_WHEN_VALUE_CHANGES_ID,
792-
handler: async (accessor: ServicesAccessor) => {
793-
const debugService = accessor.get(IDebugService);
794-
if (dataBreakpointInfoResponse) {
795-
await debugService.addDataBreakpoint({ description: dataBreakpointInfoResponse.description, src: { type: DataBreakpointSetType.Variable, dataId: dataBreakpointInfoResponse.dataId! }, canPersist: !!dataBreakpointInfoResponse.canPersist, accessTypes: dataBreakpointInfoResponse.accessTypes, accessType: 'write' });
796-
}
797-
}
798-
});
799-
800-
export const BREAK_WHEN_VALUE_IS_ACCESSED_ID = 'debug.breakWhenValueIsAccessed';
801-
CommandsRegistry.registerCommand({
802-
id: BREAK_WHEN_VALUE_IS_ACCESSED_ID,
803-
handler: async (accessor: ServicesAccessor) => {
804-
const debugService = accessor.get(IDebugService);
805-
if (dataBreakpointInfoResponse) {
806-
await debugService.addDataBreakpoint({ description: dataBreakpointInfoResponse.description, src: { type: DataBreakpointSetType.Variable, dataId: dataBreakpointInfoResponse.dataId! }, canPersist: !!dataBreakpointInfoResponse.canPersist, accessTypes: dataBreakpointInfoResponse.accessTypes, accessType: 'readWrite' });
807-
}
808-
}
809-
});
810-
811-
export const BREAK_WHEN_VALUE_IS_READ_ID = 'debug.breakWhenValueIsRead';
812-
CommandsRegistry.registerCommand({
813-
id: BREAK_WHEN_VALUE_IS_READ_ID,
814-
handler: async (accessor: ServicesAccessor) => {
815-
const debugService = accessor.get(IDebugService);
816-
if (dataBreakpointInfoResponse) {
817-
await debugService.addDataBreakpoint({ description: dataBreakpointInfoResponse.description, src: { type: DataBreakpointSetType.Variable, dataId: dataBreakpointInfoResponse.dataId! }, canPersist: !!dataBreakpointInfoResponse.canPersist, accessTypes: dataBreakpointInfoResponse.accessTypes, accessType: 'read' });
818-
}
819-
}
820-
});
821-
822789
CommandsRegistry.registerCommand({
823790
metadata: {
824791
description: COPY_EVALUATE_PATH_LABEL,

0 commit comments

Comments
 (0)