Path: blob/main/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts
5236 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { getDomNodePagePosition } from '../../../../base/browser/dom.js';6import { toAction } from '../../../../base/common/actions.js';7import { KeyChord, KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';8import { ICodeEditor } from '../../../../editor/browser/editorBrowser.js';9import { EditorAction, IActionOptions, registerEditorAction } from '../../../../editor/browser/editorExtensions.js';10import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';11import { Position } from '../../../../editor/common/core/position.js';12import { EditorContextKeys } from '../../../../editor/common/editorContextKeys.js';13import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js';14import { MessageController } from '../../../../editor/contrib/message/browser/messageController.js';15import * as nls from '../../../../nls.js';16import { ILocalizedString } from '../../../../platform/action/common/action.js';17import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js';18import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';19import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';20import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';21import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';22import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';23import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';24import { PanelFocusContext } from '../../../common/contextkeys.js';25import { ChatContextKeys } from '../../chat/common/actions/chatContextKeys.js';26import { openBreakpointSource } from './breakpointsView.js';27import { DisassemblyView, IDisassembledInstructionEntry } from './disassemblyView.js';28import { Repl } from './repl.js';29import { BREAKPOINT_EDITOR_CONTRIBUTION_ID, BreakpointWidgetContext, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_DEBUG_STATE, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_DISASSEMBLY_VIEW_FOCUS, CONTEXT_EXCEPTION_WIDGET_VISIBLE, CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE, CONTEXT_IN_DEBUG_MODE, CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution, IDebugConfiguration, IDebugEditorContribution, IDebugService, REPL_VIEW_ID, WATCH_VIEW_ID } from '../common/debug.js';30import { getEvaluatableExpressionAtPosition } from '../common/debugUtils.js';31import { DisassemblyViewInput } from '../common/disassemblyViewInput.js';32import { IEditorService } from '../../../services/editor/common/editorService.js';33import { IViewsService } from '../../../services/views/common/viewsService.js';34import { TOGGLE_BREAKPOINT_ID } from '../../../../workbench/contrib/debug/browser/debugCommands.js';3536class ToggleBreakpointAction extends Action2 {37constructor() {38super({39id: TOGGLE_BREAKPOINT_ID,40title: {41...nls.localize2('toggleBreakpointAction', "Toggle Breakpoint"),42mnemonicTitle: nls.localize({ key: 'miToggleBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breakpoint"),43},44category: nls.localize2('debugCategory', "Debug"),45f1: true,46precondition: CONTEXT_DEBUGGERS_AVAILABLE,47keybinding: {48when: ContextKeyExpr.or(EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLY_VIEW_FOCUS),49primary: KeyCode.F9,50weight: KeybindingWeight.EditorContrib51},52menu: [{53id: MenuId.MenubarDebugMenu,54when: CONTEXT_DEBUGGERS_AVAILABLE,55group: '4_new_breakpoint',56order: 157}]58});59}6061async run(accessor: ServicesAccessor, entry?: IDisassembledInstructionEntry): Promise<void> {62const editorService = accessor.get(IEditorService);63const debugService = accessor.get(IDebugService);6465const activePane = editorService.activeEditorPane;66if (activePane instanceof DisassemblyView) {67const location = entry ? activePane.getAddressAndOffset(entry) : activePane.focusedAddressAndOffset;68if (location) {69const bps = debugService.getModel().getInstructionBreakpoints();70const toRemove = bps.find(bp => bp.address === location.address);71if (toRemove) {72debugService.removeInstructionBreakpoints(toRemove.instructionReference, toRemove.offset);73} else {74debugService.addInstructionBreakpoint({ instructionReference: location.reference, offset: location.offset, address: location.address, canPersist: false });75}76}77return;78}7980const codeEditorService = accessor.get(ICodeEditorService);81const editor = codeEditorService.getFocusedCodeEditor() || codeEditorService.getActiveCodeEditor();82if (editor?.hasModel()) {83const modelUri = editor.getModel().uri;84const canSet = debugService.canSetBreakpointsIn(editor.getModel());85// Does not account for multi line selections, Set to remove multiple cursor on the same line86const lineNumbers = [...new Set(editor.getSelections().map(s => s.getPosition().lineNumber))];8788await Promise.all(lineNumbers.map(async line => {89const bps = debugService.getModel().getBreakpoints({ lineNumber: line, uri: modelUri });90if (bps.length) {91await Promise.all(bps.map(bp => debugService.removeBreakpoints(bp.getId())));92} else if (canSet) {93await debugService.addBreakpoints(modelUri, [{ lineNumber: line }]);94}95}));96}97}98}99100class ConditionalBreakpointAction extends EditorAction {101constructor() {102super({103id: 'editor.debug.action.conditionalBreakpoint',104label: nls.localize2('conditionalBreakpointEditorAction', "Debug: Add Conditional Breakpoint..."),105precondition: CONTEXT_DEBUGGERS_AVAILABLE,106menuOpts: {107menuId: MenuId.MenubarNewBreakpointMenu,108title: nls.localize({ key: 'miConditionalBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Conditional Breakpoint..."),109group: '1_breakpoints',110order: 1,111when: CONTEXT_DEBUGGERS_AVAILABLE112}113});114}115116async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {117const debugService = accessor.get(IDebugService);118119const position = editor.getPosition();120if (position && editor.hasModel() && debugService.canSetBreakpointsIn(editor.getModel())) {121editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(position.lineNumber, undefined, BreakpointWidgetContext.CONDITION);122}123}124}125126class LogPointAction extends EditorAction {127128constructor() {129super({130id: 'editor.debug.action.addLogPoint',131label: nls.localize2('logPointEditorAction', "Debug: Add Logpoint..."),132precondition: CONTEXT_DEBUGGERS_AVAILABLE,133menuOpts: [134{135menuId: MenuId.MenubarNewBreakpointMenu,136title: nls.localize({ key: 'miLogPoint', comment: ['&& denotes a mnemonic'] }, "&&Logpoint..."),137group: '1_breakpoints',138order: 4,139when: CONTEXT_DEBUGGERS_AVAILABLE,140}141]142});143}144145async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {146const debugService = accessor.get(IDebugService);147148const position = editor.getPosition();149if (position && editor.hasModel() && debugService.canSetBreakpointsIn(editor.getModel())) {150editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(position.lineNumber, position.column, BreakpointWidgetContext.LOG_MESSAGE);151}152}153}154155class TriggerByBreakpointAction extends EditorAction {156157constructor() {158super({159id: 'editor.debug.action.triggerByBreakpoint',160label: nls.localize('triggerByBreakpointEditorAction', "Debug: Add Triggered Breakpoint..."),161precondition: CONTEXT_DEBUGGERS_AVAILABLE,162alias: 'Debug: Triggered Breakpoint...',163menuOpts: [164{165menuId: MenuId.MenubarNewBreakpointMenu,166title: nls.localize({ key: 'miTriggerByBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Triggered Breakpoint..."),167group: '1_breakpoints',168order: 4,169when: CONTEXT_DEBUGGERS_AVAILABLE,170}171]172});173}174175async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {176const debugService = accessor.get(IDebugService);177178const position = editor.getPosition();179if (position && editor.hasModel() && debugService.canSetBreakpointsIn(editor.getModel())) {180editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(position.lineNumber, position.column, BreakpointWidgetContext.TRIGGER_POINT);181}182}183}184185class EditBreakpointAction extends EditorAction {186constructor() {187super({188id: 'editor.debug.action.editBreakpoint',189label: nls.localize('EditBreakpointEditorAction', "Debug: Edit Breakpoint"),190alias: 'Debug: Edit Existing Breakpoint',191precondition: CONTEXT_DEBUGGERS_AVAILABLE,192menuOpts: {193menuId: MenuId.MenubarNewBreakpointMenu,194title: nls.localize({ key: 'miEditBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Edit Breakpoint"),195group: '1_breakpoints',196order: 1,197when: CONTEXT_DEBUGGERS_AVAILABLE198}199});200}201202async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {203const debugService = accessor.get(IDebugService);204205const position = editor.getPosition();206const debugModel = debugService.getModel();207if (!(editor.hasModel() && position)) {208return;209}210211const lineBreakpoints = debugModel.getBreakpoints({ lineNumber: position.lineNumber });212if (lineBreakpoints.length === 0) {213return;214}215216const breakpointDistances = lineBreakpoints.map(b => {217if (!b.column) {218return position.column;219}220221return Math.abs(b.column - position.column);222});223const closestBreakpointIndex = breakpointDistances.indexOf(Math.min(...breakpointDistances));224const closestBreakpoint = lineBreakpoints[closestBreakpointIndex];225226editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(closestBreakpoint.lineNumber, closestBreakpoint.column);227}228}229230class OpenDisassemblyViewAction extends Action2 {231232public static readonly ID = 'debug.action.openDisassemblyView';233234constructor() {235super({236id: OpenDisassemblyViewAction.ID,237title: {238...nls.localize2('openDisassemblyView', "Open Disassembly View"),239mnemonicTitle: nls.localize({ key: 'miDisassemblyView', comment: ['&& denotes a mnemonic'] }, "&&DisassemblyView"),240},241precondition: CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE,242menu: [243{244id: MenuId.EditorContext,245group: 'debug',246order: 5,247when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, PanelFocusContext.toNegated(), CONTEXT_DEBUG_STATE.isEqualTo('stopped'), EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST)248},249{250id: MenuId.DebugCallStackContext,251group: 'z_commands',252order: 50,253when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('stackFrame'), CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED)254},255{256id: MenuId.CommandPalette,257when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED)258}259]260});261}262263run(accessor: ServicesAccessor): void {264const editorService = accessor.get(IEditorService);265editorService.openEditor(DisassemblyViewInput.instance, { pinned: true, revealIfOpened: true });266}267}268269class ToggleDisassemblyViewSourceCodeAction extends Action2 {270271public static readonly ID = 'debug.action.toggleDisassemblyViewSourceCode';272public static readonly configID: string = 'debug.disassemblyView.showSourceCode';273274constructor() {275super({276id: ToggleDisassemblyViewSourceCodeAction.ID,277title: {278...nls.localize2('toggleDisassemblyViewSourceCode', "Toggle Source Code in Disassembly View"),279mnemonicTitle: nls.localize({ key: 'mitogglesource', comment: ['&& denotes a mnemonic'] }, "&&ToggleSource"),280},281metadata: {282description: nls.localize2('toggleDisassemblyViewSourceCodeDescription', 'Shows or hides source code in disassembly')283},284f1: true,285});286}287288run(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void {289const configService = accessor.get(IConfigurationService);290if (configService) {291const value = configService.getValue<IDebugConfiguration>('debug').disassemblyView.showSourceCode;292configService.updateValue(ToggleDisassemblyViewSourceCodeAction.configID, !value);293}294}295}296297export class RunToCursorAction extends EditorAction {298299public static readonly ID = 'editor.debug.action.runToCursor';300public static readonly LABEL: ILocalizedString = nls.localize2('runToCursor', "Run to Cursor");301302constructor() {303super({304id: RunToCursorAction.ID,305label: RunToCursorAction.LABEL.value,306alias: 'Debug: Run to Cursor',307precondition: ContextKeyExpr.and(308CONTEXT_DEBUGGERS_AVAILABLE,309PanelFocusContext.toNegated(),310ContextKeyExpr.or(EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLY_VIEW_FOCUS),311ChatContextKeys.inChatSession.negate()312),313contextMenuOpts: {314group: 'debug',315order: 2,316when: CONTEXT_IN_DEBUG_MODE317}318});319}320321async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {322const position = editor.getPosition();323if (!(editor.hasModel() && position)) {324return;325}326const uri = editor.getModel().uri;327328const debugService = accessor.get(IDebugService);329const viewModel = debugService.getViewModel();330const uriIdentityService = accessor.get(IUriIdentityService);331332let column: number | undefined = undefined;333const focusedStackFrame = viewModel.focusedStackFrame;334if (focusedStackFrame && uriIdentityService.extUri.isEqual(focusedStackFrame.source.uri, uri) && focusedStackFrame.range.startLineNumber === position.lineNumber) {335// If the cursor is on a line different than the one the debugger is currently paused on, then send the breakpoint on the line without a column336// otherwise set it at the precise column #102199337column = position.column;338}339await debugService.runTo(uri, position.lineNumber, column);340}341}342343export class SelectionToReplAction extends EditorAction {344345public static readonly ID = 'editor.debug.action.selectionToRepl';346public static readonly LABEL: ILocalizedString = nls.localize2('evaluateInDebugConsole', "Evaluate in Debug Console");347348constructor() {349super({350id: SelectionToReplAction.ID,351label: SelectionToReplAction.LABEL.value,352alias: 'Debug: Evaluate in Console',353precondition: ContextKeyExpr.and(354CONTEXT_IN_DEBUG_MODE,355EditorContextKeys.editorTextFocus,356ChatContextKeys.inChatSession.negate()),357contextMenuOpts: {358group: 'debug',359order: 0360}361});362}363364async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {365const debugService = accessor.get(IDebugService);366const viewsService = accessor.get(IViewsService);367const viewModel = debugService.getViewModel();368const session = viewModel.focusedSession;369if (!editor.hasModel() || !session) {370return;371}372373const selection = editor.getSelection();374let text: string;375if (selection.isEmpty()) {376text = editor.getModel().getLineContent(selection.selectionStartLineNumber).trim();377} else {378text = editor.getModel().getValueInRange(selection);379}380381const replView = await viewsService.openView(REPL_VIEW_ID, false) as Repl | undefined;382replView?.sendReplInput(text);383}384}385386export class SelectionToWatchExpressionsAction extends EditorAction {387388public static readonly ID = 'editor.debug.action.selectionToWatch';389public static readonly LABEL: ILocalizedString = nls.localize2('addToWatch', "Add to Watch");390391constructor() {392super({393id: SelectionToWatchExpressionsAction.ID,394label: SelectionToWatchExpressionsAction.LABEL.value,395alias: 'Debug: Add to Watch',396precondition: ContextKeyExpr.and(397CONTEXT_IN_DEBUG_MODE,398EditorContextKeys.editorTextFocus,399ChatContextKeys.inChatSession.negate()),400contextMenuOpts: {401group: 'debug',402order: 1403}404});405}406407async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {408const debugService = accessor.get(IDebugService);409const viewsService = accessor.get(IViewsService);410const languageFeaturesService = accessor.get(ILanguageFeaturesService);411if (!editor.hasModel()) {412return;413}414415let expression: string | undefined = undefined;416417const model = editor.getModel();418const selection = editor.getSelection();419420if (!selection.isEmpty()) {421expression = model.getValueInRange(selection);422} else {423const position = editor.getPosition();424const evaluatableExpression = await getEvaluatableExpressionAtPosition(languageFeaturesService, model, position);425if (!evaluatableExpression) {426return;427}428expression = evaluatableExpression.matchingExpression;429}430431if (!expression) {432return;433}434435await viewsService.openView(WATCH_VIEW_ID);436debugService.addWatchExpression(expression);437}438}439440class ShowDebugHoverAction extends EditorAction {441442constructor() {443super({444id: 'editor.debug.action.showDebugHover',445label: nls.localize2('showDebugHover', "Debug: Show Hover"),446precondition: CONTEXT_IN_DEBUG_MODE,447kbOpts: {448kbExpr: EditorContextKeys.editorTextFocus,449primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyI),450weight: KeybindingWeight.EditorContrib451}452});453}454455async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {456const position = editor.getPosition();457if (!position || !editor.hasModel()) {458return;459}460461return editor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID)?.showHover(position, true);462}463}464465const NO_TARGETS_MESSAGE = nls.localize('editor.debug.action.stepIntoTargets.notAvailable', "Step targets are not available here");466467class StepIntoTargetsAction extends EditorAction {468469public static readonly ID = 'editor.debug.action.stepIntoTargets';470public static readonly LABEL = nls.localize({ key: 'stepIntoTargets', comment: ['Step Into Targets lets the user step into an exact function he or she is interested in.'] }, "Step Into Target");471472constructor() {473super({474id: StepIntoTargetsAction.ID,475label: StepIntoTargetsAction.LABEL,476alias: 'Debug: Step Into Target',477precondition: ContextKeyExpr.and(CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), EditorContextKeys.editorTextFocus),478contextMenuOpts: {479group: 'debug',480order: 1.5481}482});483}484485async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {486const debugService = accessor.get(IDebugService);487const contextMenuService = accessor.get(IContextMenuService);488const uriIdentityService = accessor.get(IUriIdentityService);489const session = debugService.getViewModel().focusedSession;490const frame = debugService.getViewModel().focusedStackFrame;491const selection = editor.getSelection();492493const targetPosition = selection?.getPosition() || (frame && { lineNumber: frame.range.startLineNumber, column: frame.range.startColumn });494495if (!session || !frame || !editor.hasModel() || !uriIdentityService.extUri.isEqual(editor.getModel().uri, frame.source.uri)) {496if (targetPosition) {497MessageController.get(editor)?.showMessage(NO_TARGETS_MESSAGE, targetPosition);498}499return;500}501502503const targets = await session.stepInTargets(frame.frameId);504if (!targets?.length) {505MessageController.get(editor)?.showMessage(NO_TARGETS_MESSAGE, targetPosition!);506return;507}508509// If there is a selection, try to find the best target with a position to step into.510if (selection) {511const positionalTargets: { start: Position; end?: Position; target: DebugProtocol.StepInTarget }[] = [];512for (const target of targets) {513if (target.line) {514positionalTargets.push({515start: new Position(target.line, target.column || 1),516end: target.endLine ? new Position(target.endLine, target.endColumn || 1) : undefined,517target518});519}520}521522positionalTargets.sort((a, b) => b.start.lineNumber - a.start.lineNumber || b.start.column - a.start.column);523524const needle = selection.getPosition();525526// Try to find a target with a start and end that is around the cursor527// position. Or, if none, whatever is before the cursor.528const best = positionalTargets.find(t => t.end && needle.isBefore(t.end) && t.start.isBeforeOrEqual(needle)) || positionalTargets.find(t => t.end === undefined && t.start.isBeforeOrEqual(needle));529if (best) {530session.stepIn(frame.thread.threadId, best.target.id);531return;532}533}534535// Otherwise, show a context menu and have the user pick a target536editor.revealLineInCenterIfOutsideViewport(frame.range.startLineNumber);537const cursorCoords = editor.getScrolledVisiblePosition(targetPosition!);538const editorCoords = getDomNodePagePosition(editor.getDomNode());539const x = editorCoords.left + cursorCoords.left;540const y = editorCoords.top + cursorCoords.top + cursorCoords.height;541542contextMenuService.showContextMenu({543getAnchor: () => ({ x, y }),544getActions: () => {545return targets.map(t => toAction({ id: `stepIntoTarget:${t.id}`, label: t.label, enabled: true, run: () => session.stepIn(frame.thread.threadId, t.id) }));546}547});548}549}550551class GoToBreakpointAction extends EditorAction {552constructor(private isNext: boolean, opts: IActionOptions) {553super(opts);554}555556async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<any> {557const debugService = accessor.get(IDebugService);558const editorService = accessor.get(IEditorService);559const uriIdentityService = accessor.get(IUriIdentityService);560561if (editor.hasModel()) {562const currentUri = editor.getModel().uri;563const currentLine = editor.getPosition().lineNumber;564//Breakpoints returned from `getBreakpoints` are already sorted.565const allEnabledBreakpoints = debugService.getModel().getBreakpoints({ enabledOnly: true });566567//Try to find breakpoint in current file568let moveBreakpoint =569this.isNext570? allEnabledBreakpoints.filter(bp => uriIdentityService.extUri.isEqual(bp.uri, currentUri) && bp.lineNumber > currentLine).shift()571: allEnabledBreakpoints.filter(bp => uriIdentityService.extUri.isEqual(bp.uri, currentUri) && bp.lineNumber < currentLine).pop();572573//Try to find breakpoints in following files574if (!moveBreakpoint) {575moveBreakpoint =576this.isNext577? allEnabledBreakpoints.filter(bp => bp.uri.toString() > currentUri.toString()).shift()578: allEnabledBreakpoints.filter(bp => bp.uri.toString() < currentUri.toString()).pop();579}580581//Move to first or last possible breakpoint582if (!moveBreakpoint && allEnabledBreakpoints.length) {583moveBreakpoint = this.isNext ? allEnabledBreakpoints[0] : allEnabledBreakpoints[allEnabledBreakpoints.length - 1];584}585586if (moveBreakpoint) {587return openBreakpointSource(moveBreakpoint, false, true, false, debugService, editorService);588}589}590}591}592593class GoToNextBreakpointAction extends GoToBreakpointAction {594constructor() {595super(true, {596id: 'editor.debug.action.goToNextBreakpoint',597label: nls.localize2('goToNextBreakpoint', "Debug: Go to Next Breakpoint"),598precondition: CONTEXT_DEBUGGERS_AVAILABLE599});600}601}602603class GoToPreviousBreakpointAction extends GoToBreakpointAction {604constructor() {605super(false, {606id: 'editor.debug.action.goToPreviousBreakpoint',607label: nls.localize2('goToPreviousBreakpoint', "Debug: Go to Previous Breakpoint"),608precondition: CONTEXT_DEBUGGERS_AVAILABLE609});610}611}612613class CloseExceptionWidgetAction extends EditorAction {614615constructor() {616super({617id: 'editor.debug.action.closeExceptionWidget',618label: nls.localize2('closeExceptionWidget', "Close Exception Widget"),619precondition: CONTEXT_EXCEPTION_WIDGET_VISIBLE,620kbOpts: {621primary: KeyCode.Escape,622weight: KeybindingWeight.EditorContrib623}624});625}626627async run(_accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {628const contribution = editor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID);629contribution?.closeExceptionWidget();630}631}632633registerAction2(OpenDisassemblyViewAction);634registerAction2(ToggleDisassemblyViewSourceCodeAction);635registerAction2(ToggleBreakpointAction);636registerEditorAction(ConditionalBreakpointAction);637registerEditorAction(LogPointAction);638registerEditorAction(TriggerByBreakpointAction);639registerEditorAction(EditBreakpointAction);640registerEditorAction(RunToCursorAction);641registerEditorAction(StepIntoTargetsAction);642registerEditorAction(SelectionToReplAction);643registerEditorAction(SelectionToWatchExpressionsAction);644registerEditorAction(ShowDebugHoverAction);645registerEditorAction(GoToNextBreakpointAction);646registerEditorAction(GoToPreviousBreakpointAction);647registerEditorAction(CloseExceptionWidgetAction);648649650