From f06db31fcc7c0534014937b6e10316e65969a4e4 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 10 Jul 2019 12:08:32 +0200 Subject: [PATCH] Debug: save view state when it changes and not on shutdown fixes #77060 --- .../contrib/debug/browser/breakpointWidget.ts | 3 +- .../debug/browser/debugEditorModelManager.ts | 3 +- .../contrib/debug/browser/debugService.ts | 80 +++++++++++-------- .../workbench/contrib/debug/common/debug.ts | 2 +- .../contrib/debug/test/common/mockDebug.ts | 4 +- 5 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts index 0c49ab2059d..7200bad0a0a 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts @@ -34,6 +34,7 @@ import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { getSimpleEditorOptions, getSimpleCodeEditorWidgetOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions'; import { IRange, Range } from 'vs/editor/common/core/range'; +import { onUnexpectedError } from 'vs/base/common/errors'; const $ = dom.$; const IPrivateBreakpointWidgetService = createDecorator('privateBreakopintWidgetService'); @@ -190,7 +191,7 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi hitCondition, logMessage }); - this.debugService.updateBreakpoints(this.breakpoint.uri, data, false); + this.debugService.updateBreakpoints(this.breakpoint.uri, data, false).then(undefined, onUnexpectedError); } else { const model = this.editor.getModel(); if (model) { diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts b/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts index b0242d1ea6e..9a4cdf0bb6e 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts @@ -15,6 +15,7 @@ import { getBreakpointMessageAndClassName } from 'vs/workbench/contrib/debug/bro import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { registerColor } from 'vs/platform/theme/common/colorRegistry'; import { localize } from 'vs/nls'; +import { onUnexpectedError } from 'vs/base/common/errors'; interface IBreakpointDecoration { decorationId: string; @@ -199,7 +200,7 @@ export class DebugEditorModelManager implements IWorkbenchContribution { } } - this.debugService.updateBreakpoints(modelUri, data, true); + this.debugService.updateBreakpoints(modelUri, data, true).then(undefined, onUnexpectedError); } private onBreakpointsChange(): void { diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index b8c811771f9..0b24d9395b1 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -133,7 +133,6 @@ export class DebugService implements IDebugService { this.viewModel = new ViewModel(contextKeyService); this.toDispose.push(this.fileService.onFileChanges(e => this.onFileChanges(e))); - this.toDispose.push(this.storageService.onWillSaveState(this.saveState, this)); this.lifecycleService.onShutdown(this.dispose, this); this.toDispose.push(this.extensionHostDebugService.onAttachSession(event => { @@ -817,67 +816,82 @@ export class DebugService implements IDebugService { addWatchExpression(name: string): void { const we = this.model.addWatchExpression(name); this.viewModel.setSelectedExpression(we); + this.storeWatchExpressions(); } renameWatchExpression(id: string, newName: string): void { - return this.model.renameWatchExpression(id, newName); + this.model.renameWatchExpression(id, newName); + this.storeWatchExpressions(); } moveWatchExpression(id: string, position: number): void { this.model.moveWatchExpression(id, position); + this.storeWatchExpressions(); } removeWatchExpressions(id?: string): void { this.model.removeWatchExpressions(id); + this.storeWatchExpressions(); } //---- breakpoints - enableOrDisableBreakpoints(enable: boolean, breakpoint?: IEnablement): Promise { + async enableOrDisableBreakpoints(enable: boolean, breakpoint?: IEnablement): Promise { if (breakpoint) { this.model.setEnablement(breakpoint, enable); if (breakpoint instanceof Breakpoint) { - return this.sendBreakpoints(breakpoint.uri); + await this.sendBreakpoints(breakpoint.uri); } else if (breakpoint instanceof FunctionBreakpoint) { - return this.sendFunctionBreakpoints(); + await this.sendFunctionBreakpoints(); + } else { + await this.sendExceptionBreakpoints(); } - - return this.sendExceptionBreakpoints(); + } else { + this.model.enableOrDisableAllBreakpoints(enable); + await this.sendAllBreakpoints(); } - - this.model.enableOrDisableAllBreakpoints(enable); - return this.sendAllBreakpoints(); + this.storeBreakpoints(); } - addBreakpoints(uri: uri, rawBreakpoints: IBreakpointData[], context: string): Promise { + async addBreakpoints(uri: uri, rawBreakpoints: IBreakpointData[], context: string): Promise { const breakpoints = this.model.addBreakpoints(uri, rawBreakpoints); breakpoints.forEach(bp => aria.status(nls.localize('breakpointAdded', "Added breakpoint, line {0}, file {1}", bp.lineNumber, uri.fsPath))); breakpoints.forEach(bp => this.telemetryDebugAddBreakpoint(bp, context)); - return this.sendBreakpoints(uri).then(() => breakpoints); + await this.sendBreakpoints(uri); + this.storeBreakpoints(); + return breakpoints; } - updateBreakpoints(uri: uri, data: Map, sendOnResourceSaved: boolean): void { + async updateBreakpoints(uri: uri, data: Map, sendOnResourceSaved: boolean): Promise { this.model.updateBreakpoints(data); if (sendOnResourceSaved) { this.breakpointsToSendOnResourceSaved.add(uri.toString()); } else { - this.sendBreakpoints(uri); + await this.sendBreakpoints(uri); } + this.storeBreakpoints(); } - removeBreakpoints(id?: string): Promise { + async removeBreakpoints(id?: string): Promise { const toRemove = this.model.getBreakpoints().filter(bp => !id || bp.getId() === id); toRemove.forEach(bp => aria.status(nls.localize('breakpointRemoved', "Removed breakpoint, line {0}, file {1}", bp.lineNumber, bp.uri.fsPath))); const urisToClear = distinct(toRemove, bp => bp.uri.toString()).map(bp => bp.uri); this.model.removeBreakpoints(toRemove); - return Promise.all(urisToClear.map(uri => this.sendBreakpoints(uri))); + await Promise.all(urisToClear.map(uri => this.sendBreakpoints(uri))); + this.storeBreakpoints(); } setBreakpointsActivated(activated: boolean): Promise { this.model.setBreakpointsActivated(activated); + if (activated) { + this.storageService.store(DEBUG_BREAKPOINTS_ACTIVATED_KEY, 'false', StorageScope.WORKSPACE); + } else { + this.storageService.remove(DEBUG_BREAKPOINTS_ACTIVATED_KEY, StorageScope.WORKSPACE); + } + return this.sendAllBreakpoints(); } @@ -886,14 +900,16 @@ export class DebugService implements IDebugService { this.viewModel.setSelectedFunctionBreakpoint(newFunctionBreakpoint); } - renameFunctionBreakpoint(id: string, newFunctionName: string): Promise { + async renameFunctionBreakpoint(id: string, newFunctionName: string): Promise { this.model.renameFunctionBreakpoint(id, newFunctionName); - return this.sendFunctionBreakpoints(); + await this.sendFunctionBreakpoints(); + this.storeBreakpoints(); } - removeFunctionBreakpoints(id?: string): Promise { + async removeFunctionBreakpoints(id?: string): Promise { this.model.removeFunctionBreakpoints(id); - return this.sendFunctionBreakpoints(); + await this.sendFunctionBreakpoints(); + this.storeBreakpoints(); } sendAllBreakpoints(session?: IDebugSession): Promise { @@ -993,7 +1009,16 @@ export class DebugService implements IDebugService { return result || []; } - private saveState(): void { + private storeWatchExpressions(): void { + const watchExpressions = this.model.getWatchExpressions(); + if (watchExpressions.length) { + this.storageService.store(DEBUG_WATCH_EXPRESSIONS_KEY, JSON.stringify(watchExpressions.map(we => ({ name: we.name, id: we.getId() }))), StorageScope.WORKSPACE); + } else { + this.storageService.remove(DEBUG_WATCH_EXPRESSIONS_KEY, StorageScope.WORKSPACE); + } + } + + private storeBreakpoints(): void { const breakpoints = this.model.getBreakpoints(); if (breakpoints.length) { this.storageService.store(DEBUG_BREAKPOINTS_KEY, JSON.stringify(breakpoints), StorageScope.WORKSPACE); @@ -1001,12 +1026,6 @@ export class DebugService implements IDebugService { this.storageService.remove(DEBUG_BREAKPOINTS_KEY, StorageScope.WORKSPACE); } - if (!this.model.areBreakpointsActivated()) { - this.storageService.store(DEBUG_BREAKPOINTS_ACTIVATED_KEY, 'false', StorageScope.WORKSPACE); - } else { - this.storageService.remove(DEBUG_BREAKPOINTS_ACTIVATED_KEY, StorageScope.WORKSPACE); - } - const functionBreakpoints = this.model.getFunctionBreakpoints(); if (functionBreakpoints.length) { this.storageService.store(DEBUG_FUNCTION_BREAKPOINTS_KEY, JSON.stringify(functionBreakpoints), StorageScope.WORKSPACE); @@ -1020,13 +1039,6 @@ export class DebugService implements IDebugService { } else { this.storageService.remove(DEBUG_EXCEPTION_BREAKPOINTS_KEY, StorageScope.WORKSPACE); } - - const watchExpressions = this.model.getWatchExpressions(); - if (watchExpressions.length) { - this.storageService.store(DEBUG_WATCH_EXPRESSIONS_KEY, JSON.stringify(watchExpressions.map(we => ({ name: we.name, id: we.getId() }))), StorageScope.WORKSPACE); - } else { - this.storageService.remove(DEBUG_WATCH_EXPRESSIONS_KEY, StorageScope.WORKSPACE); - } } //---- telemetry diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 98ca7fc8d37..363f6eeb346 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -722,7 +722,7 @@ export interface IDebugService { /** * Updates the breakpoints. */ - updateBreakpoints(uri: uri, data: Map, sendOnResourceSaved: boolean): void; + updateBreakpoints(uri: uri, data: Map, sendOnResourceSaved: boolean): Promise; /** * Enables or disables all breakpoints. If breakpoint is passed only enables or disables the passed breakpoint. diff --git a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts index e901017e024..bae3cd2b832 100644 --- a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts @@ -51,7 +51,9 @@ export class MockDebugService implements IDebugService { throw new Error('not implemented'); } - public updateBreakpoints(uri: uri, data: Map, sendOnResourceSaved: boolean): void { } + public updateBreakpoints(uri: uri, data: Map, sendOnResourceSaved: boolean): Promise { + throw new Error('not implemented'); + } public enableOrDisableBreakpoints(enabled: boolean): Promise { throw new Error('not implemented'); -- GitLab