debug: show progress via notifications

#92253
This commit is contained in:
isidor 2020-03-18 18:05:21 +01:00
parent 354657c351
commit 999fd719b2
3 changed files with 60 additions and 56 deletions

View file

@ -54,6 +54,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from 'vs/platform/quickinput/common/quickAccess';
import { StartDebugQuickAccessProvider } from 'vs/workbench/contrib/debug/browser/debugQuickAccess';
import { DebugProgressContribution } from 'vs/workbench/contrib/debug/browser/debugProgress';
class OpenDebugViewletAction extends ShowViewletAction {
public static readonly ID = VIEWLET_ID;
@ -298,6 +299,7 @@ configurationRegistry.registerConfiguration({
// Register Debug Status
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugStatusContribution, LifecyclePhase.Eventually);
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugProgressContribution, LifecyclePhase.Eventually);
// Debug toolbar

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IDebugService, VIEWLET_ID } from 'vs/workbench/contrib/debug/common/debug';
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
export class DebugProgressContribution implements IWorkbenchContribution {
private toDispose: IDisposable[] = [];
constructor(
@IDebugService private readonly debugService: IDebugService,
@IProgressService private readonly progressService: IProgressService
) {
let progressListener: IDisposable;
this.toDispose.push(this.debugService.getViewModel().onDidFocusSession(session => {
if (progressListener) {
progressListener.dispose();
}
if (session) {
progressListener = session.onDidProgressStart(async progressStartEvent => {
const promise = new Promise<void>(r => {
// Show progress until a progress end event comes or the session ends
const listener = Event.any(Event.filter(session.onDidProgressEnd, e => e.body.progressId === progressStartEvent.body.progressId),
session.onDidEndAdapter)(() => {
listener.dispose();
r();
});
});
this.progressService.withProgress({ location: VIEWLET_ID }, () => promise);
this.progressService.withProgress({
location: ProgressLocation.Notification,
title: progressStartEvent.body.title,
cancellable: progressStartEvent.body.cancellable,
silent: true
}, () => promise, () => session.cancel(progressStartEvent.body.progressId));
});
}
}));
}
dispose(): void {
dispose(this.toDispose);
}
}

View file

@ -5,11 +5,10 @@
import 'vs/css!./media/debugViewlet';
import * as nls from 'vs/nls';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction } from 'vs/base/common/actions';
import * as DOM from 'vs/base/browser/dom';
import { Event } from 'vs/base/common/event';
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IDebugService, VIEWLET_ID, State, BREAKPOINTS_VIEW_ID, IDebugConfiguration, DEBUG_PANEL_ID, CONTEXT_DEBUG_UX, CONTEXT_DEBUG_UX_KEY, IDebugSession } from 'vs/workbench/contrib/debug/common/debug';
import { IDebugService, VIEWLET_ID, State, BREAKPOINTS_VIEW_ID, IDebugConfiguration, DEBUG_PANEL_ID, CONTEXT_DEBUG_UX, CONTEXT_DEBUG_UX_KEY } from 'vs/workbench/contrib/debug/common/debug';
import { StartAction, ConfigureAction, SelectAndStartAction, FocusSessionAction } from 'vs/workbench/contrib/debug/browser/debugActions';
import { StartDebugActionViewItem, FocusSessionActionViewItem } from 'vs/workbench/contrib/debug/browser/debugActionViewItems';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@ -44,7 +43,6 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
private paneListeners = new Map<string, IDisposable>();
private debugToolBarMenu: IMenu | undefined;
private disposeOnTitleUpdate: IDisposable | undefined;
private progressEvents: { event: DebugProtocol.ProgressStartEvent, session: IDebugSession }[] = [];
constructor(
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@ -81,38 +79,6 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
this.updateTitleArea();
}
}));
let progressListener: IDisposable;
this._register(this.debugService.getViewModel().onDidFocusSession(session => {
if (progressListener) {
progressListener.dispose();
}
if (session) {
progressListener = session.onDidProgressStart(async progressStartEvent => {
// Update title area to show the cancel progress action
this.progressEvents.push({ session: session, event: progressStartEvent });
if (progressStartEvent.body.cancellable) {
this.cancelAction.tooltip = nls.localize('cancelProgress', "Cancel {0}", progressStartEvent.body.title);
this.updateTitleArea();
}
await this.progressService.withProgress({ location: VIEWLET_ID }, () => {
return new Promise(r => {
// Show progress until a progress end event comes or the session ends
const listener = Event.any(Event.filter(session.onDidProgressEnd, e => e.body.progressId === progressStartEvent.body.progressId),
session.onDidEndAdapter)(() => {
listener.dispose();
r();
});
});
});
this.progressEvents = this.progressEvents.filter(pe => pe.event.body.progressId !== progressStartEvent.body.progressId);
if (progressStartEvent.body.cancellable) {
this.cancelAction.tooltip = nls.localize('cancel', "Cancel");
this.updateTitleArea();
}
});
}
}));
}
create(parent: HTMLElement): void {
@ -145,16 +111,6 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
return this._register(this.instantiationService.createInstance(OpenDebugPanelAction, OpenDebugPanelAction.ID, OpenDebugPanelAction.LABEL));
}
@memoize
private get cancelAction(): Action {
return this._register(new Action('debug.cancelProgress', nls.localize('cancel', "Cancel"), 'debug-action codicon codicon-stop', true, async () => {
const progressEvent = this.progressEvents.filter(e => e.event.body.cancellable).pop();
if (progressEvent) {
await progressEvent.session.cancel(progressEvent.event.body.progressId);
}
}));
}
@memoize
private get selectAndStartAction(): SelectAndStartAction {
return this._register(this.instantiationService.createInstance(SelectAndStartAction, SelectAndStartAction.ID, nls.localize('startAdditionalSession', "Start Additional Session")));
@ -165,7 +121,6 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
return [];
}
let result: IAction[];
if (!this.showInitialDebugActions) {
if (!this.debugToolBarMenu) {
@ -179,18 +134,14 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
}
this.disposeOnTitleUpdate = disposable;
result = actions;
} else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
result = [this.toggleReplAction];
} else {
result = [this.startAction, this.configureAction, this.toggleReplAction];
return actions;
}
if (this.progressEvents.filter(e => e.event.body.cancellable).length) {
result.unshift(this.cancelAction);
if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
return [this.toggleReplAction];
}
return result;
return [this.startAction, this.configureAction, this.toggleReplAction];
}
get showInitialDebugActions(): boolean {
@ -235,7 +186,7 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
}
if (state === State.Initializing) {
this.progressService.withProgress({ location: VIEWLET_ID }, _progress => {
this.progressService.withProgress({ location: VIEWLET_ID, }, _progress => {
return new Promise(resolve => this.progressResolve = resolve);
});
}