debug: add ability to close exception widget

fixes #88217
This commit is contained in:
isidor
2020-11-10 19:17:02 +01:00
parent 92b9426701
commit 57203b243d
5 changed files with 69 additions and 17 deletions
@@ -9,7 +9,7 @@ import { Range } from 'vs/editor/common/core/range';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { ServicesAccessor, registerEditorAction, EditorAction, IActionOptions } from 'vs/editor/browser/editorExtensions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IDebugService, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE, State, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, BreakpointWidgetContext, IBreakpoint, BREAKPOINT_EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution, REPL_VIEW_ID, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, WATCH_VIEW_ID, CONTEXT_DEBUGGERS_AVAILABLE } from 'vs/workbench/contrib/debug/common/debug';
import { IDebugService, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE, State, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, BreakpointWidgetContext, IBreakpoint, BREAKPOINT_EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution, REPL_VIEW_ID, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, WATCH_VIEW_ID, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_EXCEPTION_WIDGET_VISIBLE } from 'vs/workbench/contrib/debug/common/debug';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { openBreakpointSource } from 'vs/workbench/contrib/debug/browser/breakpointsView';
@@ -454,6 +454,27 @@ class GoToPreviousBreakpointAction extends GoToBreakpointAction {
}
}
class CloseExceptionWidgetAction extends EditorAction {
constructor() {
super({
id: 'editor.debug.action.closeExceptionWidget',
label: nls.localize('closeExceptionWidget', "Close Exception Widget"),
alias: 'Close Exception Widget',
precondition: CONTEXT_EXCEPTION_WIDGET_VISIBLE,
kbOpts: {
primary: KeyCode.Escape,
weight: KeybindingWeight.EditorContrib
}
});
}
async run(_accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
const contribution = editor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID);
contribution.closeExceptionWidget();
}
}
export function registerEditorActions(): void {
registerEditorAction(ToggleBreakpointAction);
registerEditorAction(ConditionalBreakpointAction);
@@ -465,4 +486,5 @@ export function registerEditorActions(): void {
registerEditorAction(ShowDebugHoverAction);
registerEditorAction(GoToNextBreakpointAction);
registerEditorAction(GoToPreviousBreakpointAction);
registerEditorAction(CloseExceptionWidgetAction);
}
@@ -21,7 +21,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IDebugEditorContribution, IDebugService, State, IStackFrame, IDebugConfiguration, IExpression, IExceptionInfo, IDebugSession } from 'vs/workbench/contrib/debug/common/debug';
import { IDebugEditorContribution, IDebugService, State, IStackFrame, IDebugConfiguration, IExpression, IExceptionInfo, IDebugSession, CONTEXT_EXCEPTION_WIDGET_VISIBLE } from 'vs/workbench/contrib/debug/common/debug';
import { ExceptionWidget } from 'vs/workbench/contrib/debug/browser/exceptionWidget';
import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets';
import { Position } from 'vs/editor/common/core/position';
@@ -39,6 +39,7 @@ import { HoverStartMode } from 'vs/editor/contrib/hover/hoverOperation';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { Event } from 'vs/base/common/event';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const LAUNCH_JSON_REGEX = /\.vscode\/launch\.json$/;
const INLINE_VALUE_DECORATION_KEY = 'inlinevaluedecoration';
@@ -173,6 +174,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {
private hoverWidget: DebugHoverWidget;
private hoverRange: Range | null = null;
private mouseDown = false;
private exceptionWidgetVisible: IContextKey<boolean>;
private static readonly MEMOIZER = createMemoizer();
private exceptionWidget: ExceptionWidget | undefined;
@@ -189,13 +191,15 @@ export class DebugEditorContribution implements IDebugEditorContribution {
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IHostService private readonly hostService: IHostService,
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
@IContextKeyService contextKeyService: IContextKeyService
) {
this.hoverWidget = this.instantiationService.createInstance(DebugHoverWidget, this.editor);
this.toDispose = [];
this.registerListeners();
this.updateConfigurationWidgetVisibility();
this.codeEditorService.registerDecorationType(INLINE_VALUE_DECORATION_KEY, {});
this.exceptionWidgetVisible = CONTEXT_EXCEPTION_WIDGET_VISIBLE.bindTo(contextKeyService);
this.toggleExceptionWidget();
}
@@ -442,12 +446,14 @@ export class DebugEditorContribution implements IDebugEditorContribution {
this.exceptionWidget = this.instantiationService.createInstance(ExceptionWidget, this.editor, exceptionInfo, debugSession);
this.exceptionWidget.show({ lineNumber, column }, 0);
this.editor.revealLine(lineNumber);
this.exceptionWidgetVisible.set(true);
}
private closeExceptionWidget(): void {
closeExceptionWidget(): void {
if (this.exceptionWidget) {
this.exceptionWidget.dispose();
this.exceptionWidget = undefined;
this.exceptionWidgetVisible.set(false);
}
}
@@ -8,7 +8,7 @@ import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/zoneWidget';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IExceptionInfo, IDebugSession } from 'vs/workbench/contrib/debug/common/debug';
import { IExceptionInfo, IDebugSession, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID } from 'vs/workbench/contrib/debug/common/debug';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeService';
import { Color } from 'vs/base/common/color';
@@ -16,6 +16,8 @@ import { registerColor } from 'vs/platform/theme/common/colorRegistry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
const $ = dom.$;
// theming
@@ -25,18 +27,19 @@ export const debugExceptionWidgetBackground = registerColor('debugExceptionWidge
export class ExceptionWidget extends ZoneWidget {
private _backgroundColor?: Color;
private backgroundColor: Color | undefined;
constructor(editor: ICodeEditor, private exceptionInfo: IExceptionInfo, private debugSession: IDebugSession | undefined,
constructor(
editor: ICodeEditor,
private exceptionInfo: IExceptionInfo,
private debugSession: IDebugSession | undefined,
@IThemeService themeService: IThemeService,
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super(editor, { showFrame: true, showArrow: true, frameWidth: 1, className: 'exception-widget-container' });
this._backgroundColor = Color.white;
this._applyTheme(themeService.getColorTheme());
this._disposables.add(themeService.onDidColorThemeChange(this._applyTheme.bind(this)));
this.applyTheme(themeService.getColorTheme());
this._disposables.add(themeService.onDidColorThemeChange(this.applyTheme.bind(this)));
this.create();
const onDidLayoutChangeScheduler = new RunOnceScheduler(() => this._doLayout(undefined, undefined), 50);
@@ -44,8 +47,8 @@ export class ExceptionWidget extends ZoneWidget {
this._disposables.add(onDidLayoutChangeScheduler);
}
private _applyTheme(theme: IColorTheme): void {
this._backgroundColor = theme.getColor(debugExceptionWidgetBackground);
private applyTheme(theme: IColorTheme): void {
this.backgroundColor = theme.getColor(debugExceptionWidgetBackground);
const frameColor = theme.getColor(debugExceptionWidgetBorder);
this.style({
arrowColor: frameColor,
@@ -55,7 +58,7 @@ export class ExceptionWidget extends ZoneWidget {
protected _applyStyles(): void {
if (this.container) {
this.container.style.backgroundColor = this._backgroundColor ? this._backgroundColor.toString() : '';
this.container.style.backgroundColor = this.backgroundColor ? this.backgroundColor.toString() : '';
}
super._applyStyles();
}
@@ -67,8 +70,19 @@ export class ExceptionWidget extends ZoneWidget {
container.style.fontSize = `${fontInfo.fontSize}px`;
container.style.lineHeight = `${fontInfo.lineHeight}px`;
let title = $('.title');
title.textContent = this.exceptionInfo.id ? nls.localize('exceptionThrownWithId', 'Exception has occurred: {0}', this.exceptionInfo.id) : nls.localize('exceptionThrown', 'Exception has occurred.');
const title = $('.title');
const label = $('.label');
dom.append(title, label);
const actions = $('.actions');
dom.append(title, actions);
label.textContent = this.exceptionInfo.id ? nls.localize('exceptionThrownWithId', 'Exception has occurred: {0}', this.exceptionInfo.id) : nls.localize('exceptionThrown', 'Exception has occurred.');
const actionBar = new ActionBar(actions);
actionBar.push(new Action('editor.closeExceptionWidget', nls.localize('close', "Close"), 'codicon codicon-close', true, async () => {
const contribution = this.editor.getContribution<IDebugEditorContribution>(EDITOR_CONTRIBUTION_ID);
contribution.closeExceptionWidget();
}), { label: false, icon: true });
dom.append(container, title);
if (this.exceptionInfo.description) {
@@ -15,9 +15,17 @@
}
.monaco-editor .zone-widget .zone-widget-container.exception-widget .title {
display: flex;
}
.monaco-editor .zone-widget .zone-widget-container.exception-widget .title .label {
font-weight: bold;
}
.monaco-editor .zone-widget .zone-widget-container.exception-widget .title .actions {
flex: 1;
}
.monaco-editor .zone-widget .zone-widget-container.exception-widget .description,
.monaco-editor .zone-widget .zone-widget-container.exception-widget .stack-trace {
font-family: var(--monaco-monospace-font);
@@ -27,7 +35,7 @@
margin-top: 0.5em;
}
.monaco-editor .zone-widget .zone-widget-container.exception-widget a {
.monaco-editor .zone-widget .zone-widget-container.exception-widget .stack-trace a {
text-decoration: underline;
cursor: pointer;
}
@@ -64,6 +64,7 @@ export const CONTEXT_DEBUG_PROTOCOL_VARIABLE_MENU_CONTEXT = new RawContextKey<st
export const CONTEXT_SET_VARIABLE_SUPPORTED = new RawContextKey<boolean>('debugSetVariableSupported', false);
export const CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED = new RawContextKey<boolean>('breakWhenValueChangesSupported', false);
export const CONTEXT_VARIABLE_EVALUATE_NAME_PRESENT = new RawContextKey<boolean>('variableEvaluateNamePresent', false);
export const CONTEXT_EXCEPTION_WIDGET_VISIBLE = new RawContextKey<boolean>('exceptionWidgetVisible', false);
export const EDITOR_CONTRIBUTION_ID = 'editor.contrib.debug';
export const BREAKPOINT_EDITOR_CONTRIBUTION_ID = 'editor.contrib.breakpoint';
@@ -935,6 +936,7 @@ export const enum BreakpointWidgetContext {
export interface IDebugEditorContribution extends editorCommon.IEditorContribution {
showHover(range: Range, focus: boolean): Promise<void>;
addLaunchConfiguration(): Promise<any>;
closeExceptionWidget(): void;
}
export interface IBreakpointEditorContribution extends editorCommon.IEditorContribution {