Path: blob/main/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts
3296 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 { Action } 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/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', "Debug: Toggle Breakpoint"),42mnemonicTitle: nls.localize({ key: 'miToggleBreakpoint', comment: ['&& denotes a mnemonic'] }, "Toggle &&Breakpoint"),43},44f1: true,45precondition: CONTEXT_DEBUGGERS_AVAILABLE,46keybinding: {47when: ContextKeyExpr.or(EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLY_VIEW_FOCUS),48primary: KeyCode.F9,49weight: KeybindingWeight.EditorContrib50},51menu: {52id: MenuId.MenubarDebugMenu,53when: CONTEXT_DEBUGGERS_AVAILABLE,54group: '4_new_breakpoint',55order: 156}57});58}5960async run(accessor: ServicesAccessor, entry?: IDisassembledInstructionEntry): Promise<void> {61const editorService = accessor.get(IEditorService);62const debugService = accessor.get(IDebugService);6364const activePane = editorService.activeEditorPane;65if (activePane instanceof DisassemblyView) {66const location = entry ? activePane.getAddressAndOffset(entry) : activePane.focusedAddressAndOffset;67if (location) {68const bps = debugService.getModel().getInstructionBreakpoints();69const toRemove = bps.find(bp => bp.address === location.address);70if (toRemove) {71debugService.removeInstructionBreakpoints(toRemove.instructionReference, toRemove.offset);72} else {73debugService.addInstructionBreakpoint({ instructionReference: location.reference, offset: location.offset, address: location.address, canPersist: false });74}75}76return;77}7879const codeEditorService = accessor.get(ICodeEditorService);80const editor = codeEditorService.getFocusedCodeEditor() || codeEditorService.getActiveCodeEditor();81if (editor?.hasModel()) {82const modelUri = editor.getModel().uri;83const canSet = debugService.canSetBreakpointsIn(editor.getModel());84// Does not account for multi line selections, Set to remove multiple cursor on the same line85const lineNumbers = [...new Set(editor.getSelections().map(s => s.getPosition().lineNumber))];8687await Promise.all(lineNumbers.map(async line => {88const bps = debugService.getModel().getBreakpoints({ lineNumber: line, uri: modelUri });89if (bps.length) {90await Promise.all(bps.map(bp => debugService.removeBreakpoints(bp.getId())));91} else if (canSet) {92await debugService.addBreakpoints(modelUri, [{ lineNumber: line }]);93}94}));95}96}97}9899class ConditionalBreakpointAction extends EditorAction {100constructor() {101super({102id: 'editor.debug.action.conditionalBreakpoint',103label: nls.localize2('conditionalBreakpointEditorAction', "Debug: Add Conditional Breakpoint..."),104precondition: CONTEXT_DEBUGGERS_AVAILABLE,105menuOpts: {106menuId: MenuId.MenubarNewBreakpointMenu,107title: nls.localize({ key: 'miConditionalBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Conditional Breakpoint..."),108group: '1_breakpoints',109order: 1,110when: CONTEXT_DEBUGGERS_AVAILABLE111}112});113}114115async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {116const debugService = accessor.get(IDebugService);117118const position = editor.getPosition();119if (position && editor.hasModel() && debugService.canSetBreakpointsIn(editor.getModel())) {120editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(position.lineNumber, undefined, BreakpointWidgetContext.CONDITION);121}122}123}124125class LogPointAction extends EditorAction {126127constructor() {128super({129id: 'editor.debug.action.addLogPoint',130label: nls.localize2('logPointEditorAction', "Debug: Add Logpoint..."),131precondition: CONTEXT_DEBUGGERS_AVAILABLE,132menuOpts: [133{134menuId: MenuId.MenubarNewBreakpointMenu,135title: nls.localize({ key: 'miLogPoint', comment: ['&& denotes a mnemonic'] }, "&&Logpoint..."),136group: '1_breakpoints',137order: 4,138when: CONTEXT_DEBUGGERS_AVAILABLE,139}140]141});142}143144async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {145const debugService = accessor.get(IDebugService);146147const position = editor.getPosition();148if (position && editor.hasModel() && debugService.canSetBreakpointsIn(editor.getModel())) {149editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(position.lineNumber, position.column, BreakpointWidgetContext.LOG_MESSAGE);150}151}152}153154class TriggerByBreakpointAction extends EditorAction {155156constructor() {157super({158id: 'editor.debug.action.triggerByBreakpoint',159label: nls.localize('triggerByBreakpointEditorAction', "Debug: Add Triggered Breakpoint..."),160precondition: CONTEXT_DEBUGGERS_AVAILABLE,161alias: 'Debug: Triggered Breakpoint...',162menuOpts: [163{164menuId: MenuId.MenubarNewBreakpointMenu,165title: nls.localize({ key: 'miTriggerByBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Triggered Breakpoint..."),166group: '1_breakpoints',167order: 4,168when: CONTEXT_DEBUGGERS_AVAILABLE,169}170]171});172}173174async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {175const debugService = accessor.get(IDebugService);176177const position = editor.getPosition();178if (position && editor.hasModel() && debugService.canSetBreakpointsIn(editor.getModel())) {179editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(position.lineNumber, position.column, BreakpointWidgetContext.TRIGGER_POINT);180}181}182}183184class EditBreakpointAction extends EditorAction {185constructor() {186super({187id: 'editor.debug.action.editBreakpoint',188label: nls.localize('EditBreakpointEditorAction', "Debug: Edit Breakpoint"),189alias: 'Debug: Edit Existing Breakpoint',190precondition: CONTEXT_DEBUGGERS_AVAILABLE,191menuOpts: {192menuId: MenuId.MenubarNewBreakpointMenu,193title: nls.localize({ key: 'miEditBreakpoint', comment: ['&& denotes a mnemonic'] }, "&&Edit Breakpoint"),194group: '1_breakpoints',195order: 1,196when: CONTEXT_DEBUGGERS_AVAILABLE197}198});199}200201async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {202const debugService = accessor.get(IDebugService);203204const position = editor.getPosition();205const debugModel = debugService.getModel();206if (!(editor.hasModel() && position)) {207return;208}209210const lineBreakpoints = debugModel.getBreakpoints({ lineNumber: position.lineNumber });211if (lineBreakpoints.length === 0) {212return;213}214215const breakpointDistances = lineBreakpoints.map(b => {216if (!b.column) {217return position.column;218}219220return Math.abs(b.column - position.column);221});222const closestBreakpointIndex = breakpointDistances.indexOf(Math.min(...breakpointDistances));223const closestBreakpoint = lineBreakpoints[closestBreakpointIndex];224225editor.getContribution<IBreakpointEditorContribution>(BREAKPOINT_EDITOR_CONTRIBUTION_ID)?.showBreakpointWidget(closestBreakpoint.lineNumber, closestBreakpoint.column);226}227}228229class OpenDisassemblyViewAction extends Action2 {230231public static readonly ID = 'debug.action.openDisassemblyView';232233constructor() {234super({235id: OpenDisassemblyViewAction.ID,236title: {237...nls.localize2('openDisassemblyView', "Open Disassembly View"),238mnemonicTitle: nls.localize({ key: 'miDisassemblyView', comment: ['&& denotes a mnemonic'] }, "&&DisassemblyView"),239},240precondition: CONTEXT_FOCUSED_STACK_FRAME_HAS_INSTRUCTION_POINTER_REFERENCE,241menu: [242{243id: MenuId.EditorContext,244group: 'debug',245order: 5,246when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, PanelFocusContext.toNegated(), CONTEXT_DEBUG_STATE.isEqualTo('stopped'), EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED, CONTEXT_LANGUAGE_SUPPORTS_DISASSEMBLE_REQUEST)247},248{249id: MenuId.DebugCallStackContext,250group: 'z_commands',251order: 50,252when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), CONTEXT_CALLSTACK_ITEM_TYPE.isEqualTo('stackFrame'), CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED)253},254{255id: MenuId.CommandPalette,256when: ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), CONTEXT_DISASSEMBLE_REQUEST_SUPPORTED)257}258]259});260}261262run(accessor: ServicesAccessor): void {263const editorService = accessor.get(IEditorService);264editorService.openEditor(DisassemblyViewInput.instance, { pinned: true, revealIfOpened: true });265}266}267268class ToggleDisassemblyViewSourceCodeAction extends Action2 {269270public static readonly ID = 'debug.action.toggleDisassemblyViewSourceCode';271public static readonly configID: string = 'debug.disassemblyView.showSourceCode';272273constructor() {274super({275id: ToggleDisassemblyViewSourceCodeAction.ID,276title: {277...nls.localize2('toggleDisassemblyViewSourceCode', "Toggle Source Code in Disassembly View"),278mnemonicTitle: nls.localize({ key: 'mitogglesource', comment: ['&& denotes a mnemonic'] }, "&&ToggleSource"),279},280metadata: {281description: nls.localize2('toggleDisassemblyViewSourceCodeDescription', 'Shows or hides source code in disassembly')282},283f1: true,284});285}286287run(accessor: ServicesAccessor, editor: ICodeEditor, ...args: any[]): void {288const configService = accessor.get(IConfigurationService);289if (configService) {290const value = configService.getValue<IDebugConfiguration>('debug').disassemblyView.showSourceCode;291configService.updateValue(ToggleDisassemblyViewSourceCodeAction.configID, !value);292}293}294}295296export class RunToCursorAction extends EditorAction {297298public static readonly ID = 'editor.debug.action.runToCursor';299public static readonly LABEL: ILocalizedString = nls.localize2('runToCursor', "Run to Cursor");300301constructor() {302super({303id: RunToCursorAction.ID,304label: RunToCursorAction.LABEL.value,305alias: 'Debug: Run to Cursor',306precondition: ContextKeyExpr.and(307CONTEXT_DEBUGGERS_AVAILABLE,308PanelFocusContext.toNegated(),309ContextKeyExpr.or(EditorContextKeys.editorTextFocus, CONTEXT_DISASSEMBLY_VIEW_FOCUS),310ChatContextKeys.inChatSession.negate()311),312contextMenuOpts: {313group: 'debug',314order: 2,315when: CONTEXT_IN_DEBUG_MODE316}317});318}319320async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {321const position = editor.getPosition();322if (!(editor.hasModel() && position)) {323return;324}325const uri = editor.getModel().uri;326327const debugService = accessor.get(IDebugService);328const viewModel = debugService.getViewModel();329const uriIdentityService = accessor.get(IUriIdentityService);330331let column: number | undefined = undefined;332const focusedStackFrame = viewModel.focusedStackFrame;333if (focusedStackFrame && uriIdentityService.extUri.isEqual(focusedStackFrame.source.uri, uri) && focusedStackFrame.range.startLineNumber === position.lineNumber) {334// 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 column335// otherwise set it at the precise column #102199336column = position.column;337}338await debugService.runTo(uri, position.lineNumber, column);339}340}341342export class SelectionToReplAction extends EditorAction {343344public static readonly ID = 'editor.debug.action.selectionToRepl';345public static readonly LABEL: ILocalizedString = nls.localize2('evaluateInDebugConsole', "Evaluate in Debug Console");346347constructor() {348super({349id: SelectionToReplAction.ID,350label: SelectionToReplAction.LABEL.value,351alias: 'Debug: Evaluate in Console',352precondition: ContextKeyExpr.and(353CONTEXT_IN_DEBUG_MODE,354EditorContextKeys.editorTextFocus,355ChatContextKeys.inChatSession.negate()),356contextMenuOpts: {357group: 'debug',358order: 0359}360});361}362363async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {364const debugService = accessor.get(IDebugService);365const viewsService = accessor.get(IViewsService);366const viewModel = debugService.getViewModel();367const session = viewModel.focusedSession;368if (!editor.hasModel() || !session) {369return;370}371372const selection = editor.getSelection();373let text: string;374if (selection.isEmpty()) {375text = editor.getModel().getLineContent(selection.selectionStartLineNumber).trim();376} else {377text = editor.getModel().getValueInRange(selection);378}379380const replView = await viewsService.openView(REPL_VIEW_ID, false) as Repl | undefined;381replView?.sendReplInput(text);382}383}384385export class SelectionToWatchExpressionsAction extends EditorAction {386387public static readonly ID = 'editor.debug.action.selectionToWatch';388public static readonly LABEL: ILocalizedString = nls.localize2('addToWatch', "Add to Watch");389390constructor() {391super({392id: SelectionToWatchExpressionsAction.ID,393label: SelectionToWatchExpressionsAction.LABEL.value,394alias: 'Debug: Add to Watch',395precondition: ContextKeyExpr.and(396CONTEXT_IN_DEBUG_MODE,397EditorContextKeys.editorTextFocus,398ChatContextKeys.inChatSession.negate()),399contextMenuOpts: {400group: 'debug',401order: 1402}403});404}405406async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {407const debugService = accessor.get(IDebugService);408const viewsService = accessor.get(IViewsService);409const languageFeaturesService = accessor.get(ILanguageFeaturesService);410if (!editor.hasModel()) {411return;412}413414let expression: string | undefined = undefined;415416const model = editor.getModel();417const selection = editor.getSelection();418419if (!selection.isEmpty()) {420expression = model.getValueInRange(selection);421} else {422const position = editor.getPosition();423const evaluatableExpression = await getEvaluatableExpressionAtPosition(languageFeaturesService, model, position);424if (!evaluatableExpression) {425return;426}427expression = evaluatableExpression.matchingExpression;428}429430if (!expression) {431return;432}433434await viewsService.openView(WATCH_VIEW_ID);435debugService.addWatchExpression(expression);436}437}438439class ShowDebugHoverAction extends EditorAction {440441constructor() {442super({443id: 'editor.debug.action.showDebugHover',444label: nls.localize2('showDebugHover', "Debug: Show Hover"),445precondition: CONTEXT_IN_DEBUG_MODE,446kbOpts: {447kbExpr: EditorContextKeys.editorTextFocus,448primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyI),449weight: KeybindingWeight.EditorContrib450}451});452}453454async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {455const position = editor.getPosition();456if (!position || !editor.hasModel()) {457return;458}459460return editor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID)?.showHover(position, true);461}462}463464const NO_TARGETS_MESSAGE = nls.localize('editor.debug.action.stepIntoTargets.notAvailable', "Step targets are not available here");465466class StepIntoTargetsAction extends EditorAction {467468public static readonly ID = 'editor.debug.action.stepIntoTargets';469public 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");470471constructor() {472super({473id: StepIntoTargetsAction.ID,474label: StepIntoTargetsAction.LABEL,475alias: 'Debug: Step Into Target',476precondition: ContextKeyExpr.and(CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), EditorContextKeys.editorTextFocus),477contextMenuOpts: {478group: 'debug',479order: 1.5480}481});482}483484async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {485const debugService = accessor.get(IDebugService);486const contextMenuService = accessor.get(IContextMenuService);487const uriIdentityService = accessor.get(IUriIdentityService);488const session = debugService.getViewModel().focusedSession;489const frame = debugService.getViewModel().focusedStackFrame;490const selection = editor.getSelection();491492const targetPosition = selection?.getPosition() || (frame && { lineNumber: frame.range.startLineNumber, column: frame.range.startColumn });493494if (!session || !frame || !editor.hasModel() || !uriIdentityService.extUri.isEqual(editor.getModel().uri, frame.source.uri)) {495if (targetPosition) {496MessageController.get(editor)?.showMessage(NO_TARGETS_MESSAGE, targetPosition);497}498return;499}500501502const targets = await session.stepInTargets(frame.frameId);503if (!targets?.length) {504MessageController.get(editor)?.showMessage(NO_TARGETS_MESSAGE, targetPosition!);505return;506}507508// If there is a selection, try to find the best target with a position to step into.509if (selection) {510const positionalTargets: { start: Position; end?: Position; target: DebugProtocol.StepInTarget }[] = [];511for (const target of targets) {512if (target.line) {513positionalTargets.push({514start: new Position(target.line, target.column || 1),515end: target.endLine ? new Position(target.endLine, target.endColumn || 1) : undefined,516target517});518}519}520521positionalTargets.sort((a, b) => b.start.lineNumber - a.start.lineNumber || b.start.column - a.start.column);522523const needle = selection.getPosition();524525// Try to find a target with a start and end that is around the cursor526// position. Or, if none, whatever is before the cursor.527const best = positionalTargets.find(t => t.end && needle.isBefore(t.end) && t.start.isBeforeOrEqual(needle)) || positionalTargets.find(t => t.end === undefined && t.start.isBeforeOrEqual(needle));528if (best) {529session.stepIn(frame.thread.threadId, best.target.id);530return;531}532}533534// Otherwise, show a context menu and have the user pick a target535editor.revealLineInCenterIfOutsideViewport(frame.range.startLineNumber);536const cursorCoords = editor.getScrolledVisiblePosition(targetPosition!);537const editorCoords = getDomNodePagePosition(editor.getDomNode());538const x = editorCoords.left + cursorCoords.left;539const y = editorCoords.top + cursorCoords.top + cursorCoords.height;540541contextMenuService.showContextMenu({542getAnchor: () => ({ x, y }),543getActions: () => {544return targets.map(t => new Action(`stepIntoTarget:${t.id}`, t.label, undefined, true, () => session.stepIn(frame.thread.threadId, t.id)));545}546});547}548}549550class GoToBreakpointAction extends EditorAction {551constructor(private isNext: boolean, opts: IActionOptions) {552super(opts);553}554555async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<any> {556const debugService = accessor.get(IDebugService);557const editorService = accessor.get(IEditorService);558const uriIdentityService = accessor.get(IUriIdentityService);559560if (editor.hasModel()) {561const currentUri = editor.getModel().uri;562const currentLine = editor.getPosition().lineNumber;563//Breakpoints returned from `getBreakpoints` are already sorted.564const allEnabledBreakpoints = debugService.getModel().getBreakpoints({ enabledOnly: true });565566//Try to find breakpoint in current file567let moveBreakpoint =568this.isNext569? allEnabledBreakpoints.filter(bp => uriIdentityService.extUri.isEqual(bp.uri, currentUri) && bp.lineNumber > currentLine).shift()570: allEnabledBreakpoints.filter(bp => uriIdentityService.extUri.isEqual(bp.uri, currentUri) && bp.lineNumber < currentLine).pop();571572//Try to find breakpoints in following files573if (!moveBreakpoint) {574moveBreakpoint =575this.isNext576? allEnabledBreakpoints.filter(bp => bp.uri.toString() > currentUri.toString()).shift()577: allEnabledBreakpoints.filter(bp => bp.uri.toString() < currentUri.toString()).pop();578}579580//Move to first or last possible breakpoint581if (!moveBreakpoint && allEnabledBreakpoints.length) {582moveBreakpoint = this.isNext ? allEnabledBreakpoints[0] : allEnabledBreakpoints[allEnabledBreakpoints.length - 1];583}584585if (moveBreakpoint) {586return openBreakpointSource(moveBreakpoint, false, true, false, debugService, editorService);587}588}589}590}591592class GoToNextBreakpointAction extends GoToBreakpointAction {593constructor() {594super(true, {595id: 'editor.debug.action.goToNextBreakpoint',596label: nls.localize2('goToNextBreakpoint', "Debug: Go to Next Breakpoint"),597precondition: CONTEXT_DEBUGGERS_AVAILABLE598});599}600}601602class GoToPreviousBreakpointAction extends GoToBreakpointAction {603constructor() {604super(false, {605id: 'editor.debug.action.goToPreviousBreakpoint',606label: nls.localize2('goToPreviousBreakpoint', "Debug: Go to Previous Breakpoint"),607precondition: CONTEXT_DEBUGGERS_AVAILABLE608});609}610}611612class CloseExceptionWidgetAction extends EditorAction {613614constructor() {615super({616id: 'editor.debug.action.closeExceptionWidget',617label: nls.localize2('closeExceptionWidget', "Close Exception Widget"),618precondition: CONTEXT_EXCEPTION_WIDGET_VISIBLE,619kbOpts: {620primary: KeyCode.Escape,621weight: KeybindingWeight.EditorContrib622}623});624}625626async run(_accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {627const contribution = editor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID);628contribution?.closeExceptionWidget();629}630}631632registerAction2(OpenDisassemblyViewAction);633registerAction2(ToggleDisassemblyViewSourceCodeAction);634registerAction2(ToggleBreakpointAction);635registerEditorAction(ConditionalBreakpointAction);636registerEditorAction(LogPointAction);637registerEditorAction(TriggerByBreakpointAction);638registerEditorAction(EditBreakpointAction);639registerEditorAction(RunToCursorAction);640registerEditorAction(StepIntoTargetsAction);641registerEditorAction(SelectionToReplAction);642registerEditorAction(SelectionToWatchExpressionsAction);643registerEditorAction(ShowDebugHoverAction);644registerEditorAction(GoToNextBreakpointAction);645registerEditorAction(GoToPreviousBreakpointAction);646registerEditorAction(CloseExceptionWidgetAction);647648649