diff --git a/extensions/typescript/package.json b/extensions/typescript/package.json index 2537eaab405..da864b42efc 100644 --- a/extensions/typescript/package.json +++ b/extensions/typescript/package.json @@ -39,7 +39,6 @@ "workspaceContains:tsconfig.json" ], "main": "./out/typescriptMain", - "enableProposedApi": true, "contributes": { "languages": [ { @@ -106,10 +105,10 @@ "description": "%typescript.check.tscVersion%" }, "typescript.check.npmIsInstalled": { - "type": "boolean", - "default": true, - "description": "%typescript.check.npmIsInstalled%" - }, + "type": "boolean", + "default": true, + "description": "%typescript.check.npmIsInstalled%" + }, "typescript.referencesCodeLens.enabled": { "type": "boolean", "default": false, @@ -403,7 +402,7 @@ "fileMatch": "tsconfig.json", "url": "./schemas/tsconfig.schema.json" }, - { + { "fileMatch": "tsconfig.*.json", "url": "http://json.schemastore.org/tsconfig" }, @@ -432,14 +431,20 @@ "name": "tsc", "owner": "typescript", "applyTo": "closedDocuments", - "fileLocation": ["relative", "${cwd}"], - "pattern": "$tsc" + "fileLocation": [ + "relative", + "${cwd}" + ], + "pattern": "$tsc" }, { "name": "tsc-watch", "owner": "typescript", "applyTo": "closedDocuments", - "fileLocation": ["relative", "${cwd}"], + "fileLocation": [ + "relative", + "${cwd}" + ], "pattern": "$tsc", "watching": { "activeOnStart": true, diff --git a/extensions/typescript/src/utils/typingsStatus.ts b/extensions/typescript/src/utils/typingsStatus.ts index d2e99326764..e6ec2bda817 100644 --- a/extensions/typescript/src/utils/typingsStatus.ts +++ b/extensions/typescript/src/utils/typingsStatus.ts @@ -3,11 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/// - 'use strict'; -import { MessageItem, workspace, Disposable, window, commands } from 'vscode'; +import { MessageItem, workspace, Disposable, ProgressLocation, window, commands } from 'vscode'; import { ITypescriptServiceClient } from '../typescriptService'; import { loadMessageBundle } from 'vscode-nls'; @@ -87,7 +85,10 @@ export class AtaProgressReporter { }); }); - window.withWindowProgress(localize('installingPackages', "Fetching data for better TypeScript IntelliSense"), () => promise); + window.withProgress({ + location: ProgressLocation.Window, + title: localize('installingPackages', "Fetching data for better TypeScript IntelliSense") + }, () => promise); } private _onEndOrTimeout(eventId: number): void { diff --git a/src/vs/platform/progress/common/progress.ts b/src/vs/platform/progress/common/progress.ts index 9fbe62637a1..f5139f273d7 100644 --- a/src/vs/platform/progress/common/progress.ts +++ b/src/vs/platform/progress/common/progress.ts @@ -56,13 +56,27 @@ export class Progress implements IProgress { } } +export enum ProgressLocation { + Scm = 1, + Window = 10, +} + +export interface IProgressOptions { + location: ProgressLocation; + title?: string; + tooltip?: string; +} + +export interface IProgressStep { + message?: string; + percentage?: number; +} + export const IProgressService2 = createDecorator('progressService2'); export interface IProgressService2 { _serviceBrand: any; - withWindowProgress(title: string, task: (progress: IProgress) => TPromise): void; - - withViewletProgress(viewletId: string, task: (progress: IProgress) => TPromise): void; + withProgress(options: IProgressOptions, task: (progress: IProgress) => TPromise): void; } diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 96422c406f0..2744ef49e7d 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -3876,15 +3876,27 @@ declare module 'vscode' { export function setStatusBarMessage(text: string): Disposable; /** - * Show progress in the Source Control viewlet while running the given callback and while - * its returned promise isn't resolve or rejected. + * ~~Show progress in the Source Control viewlet while running the given callback and while + * its returned promise isn't resolve or rejected.~~ * * @param task A callback returning a promise. Progress increments can be reported with * the provided [progress](#Progress)-object. - * @return The thenable the task did return. + * @return The thenable the task did rseturn. + * + * @deprecated Use `withProgress` instead. */ export function withScmProgress(task: (progress: Progress) => Thenable): Thenable; + /** + * Show progress in the editor. Progress is shown while running the given callback + * and while the promise it returned isn't resolved nor rejected. The location at which + * progress should show (and other details) is defined via the passed [`ProgressOptions`](#ProgressOptions). + * + * @param task A callback returning a promise. Progress state can be reported with + * the provided [progress](#Progress)-object. + * @return The thenable the task-callback returned. + */ + export function withProgress(options: ProgressOptions, task: (progress: Progress<{ message?: string; percentage?: number }>) => Thenable): Thenable; /** * Creates a status bar [item](#StatusBarItem). @@ -3917,7 +3929,7 @@ declare module 'vscode' { } /** - * Value-object describing what options formatting should use. + * Value-object describing what options a terminal should use. */ export interface TerminalOptions { /** @@ -3936,6 +3948,41 @@ declare module 'vscode' { shellArgs?: string[]; } + /** + * A location in the editor at which progress information can be shown. It depends on the + * location how progress is visually represented. + */ + export enum ProgressLocation { + + /** + * Show progress for the scm viewlet, as overlay for the icon and as progress bar + * inside the viewlet (when visible). + */ + Scm = 1, + + /** + * Show progress in the status bar of the editor. + */ + Window = 10 + } + + /** + * Value-object describing where and how progress should show. + */ + export interface ProgressOptions { + + /** + * The location at which progress should show. + */ + location: ProgressLocation; + + /** + * A human-readable string which will be used to describe the + * operation. + */ + title?: string; + } + /** * An event describing an individual change in the text of a [document](#TextDocument). */ diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 41a69f498f7..f72a9baa873 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -524,14 +524,6 @@ declare module 'vscode' { export namespace window { - /** - * Show window-wide progress, e.g. in the status bar, for the provided task. The task is - * considering running as long as the promise it returned isn't resolved or rejected. - * - * @param task A function callback that represents a long running operation. - */ - export function withWindowProgress(title: string, task: (progress: Progress, token: CancellationToken) => Thenable): Thenable; - export function sampleFunction(): Thenable; } diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 01d024254a4..a465e11886a 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -344,11 +344,11 @@ export function createApiFactory( setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): vscode.Disposable { return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable); }, - withWindowProgress: proposedApiFunction(extension, (title: string, task: (progress: vscode.Progress, token: vscode.CancellationToken) => Thenable): Thenable => { - return extHostProgress.withWindowProgress(extension, title, task); - }), withScmProgress(task: (progress: vscode.Progress) => Thenable) { - return extHostProgress.withScmProgress(extension, task); + return extHostProgress.withProgress(extension, { location: extHostTypes.ProgressLocation.Scm }, task); + }, + withProgress(options: vscode.ProgressOptions, task: (progress: vscode.Progress<{ message?: string; percentage?: number }>) => Thenable) { + return extHostProgress.withProgress(extension, options, task); }, createOutputChannel(name: string): vscode.OutputChannel { return extHostOutputService.createOutputChannel(name); @@ -526,6 +526,7 @@ export function createApiFactory( Uri: URI, ViewColumn: extHostTypes.ViewColumn, WorkspaceEdit: extHostTypes.WorkspaceEdit, + ProgressLocation: extHostTypes.ProgressLocation, // functions FileLocationKind: extHostTypes.FileLocationKind, ApplyToKind: extHostTypes.ApplyToKind, diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 4b3236f44af..4c4f95ed22c 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -23,6 +23,7 @@ import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/ import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; import { IWorkspace } from 'vs/platform/workspace/common/workspace'; +import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress'; import * as editorCommon from 'vs/editor/common/editorCommon'; import * as modes from 'vs/editor/common/modes'; @@ -202,9 +203,8 @@ export abstract class MainThreadOutputServiceShape { export abstract class MainThreadProgressShape { - $startWindow(handle: number, title: string): void { throw ni(); }; - $startScm(handle: number): void { throw ni(); }; - $progressReport(handle: number, message: string): void { throw ni(); } + $startProgress(handle: number, options: IProgressOptions): void { throw ni(); }; + $progressReport(handle: number, message: IProgressStep): void { throw ni(); } $progressEnd(handle: number): void { throw ni(); } } diff --git a/src/vs/workbench/api/node/extHostProgress.ts b/src/vs/workbench/api/node/extHostProgress.ts index 237aae60d30..db1761100ef 100644 --- a/src/vs/workbench/api/node/extHostProgress.ts +++ b/src/vs/workbench/api/node/extHostProgress.ts @@ -4,9 +4,11 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { Progress, CancellationToken } from 'vscode'; +import { Progress, ProgressOptions, CancellationToken } from 'vscode'; import { MainThreadProgressShape } from './extHost.protocol'; +import { ProgressLocation } from './extHostTypeConverters'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IProgressStep } from "vs/platform/progress/common/progress"; export class ExtHostProgress { @@ -17,23 +19,18 @@ export class ExtHostProgress { this._proxy = proxy; } - withWindowProgress(extension: IExtensionDescription, title: string, task: (progress: Progress, token: CancellationToken) => Thenable): Thenable { + withProgress(extension: IExtensionDescription, options: ProgressOptions, task: (progress: Progress, token: CancellationToken) => Thenable): Thenable { const handle = this._handles++; - this._proxy.$startWindow(handle, title); + const { title, location } = options; + this._proxy.$startProgress(handle, { location: ProgressLocation.from(location), title, tooltip: extension.name }); return this._withProgress(handle, task); } - withScmProgress(extension: IExtensionDescription, task: (progress: Progress) => Thenable): Thenable { - const handle = this._handles++; - this._proxy.$startScm(handle); - return this._withProgress(handle, task); - } - - private _withProgress(handle: number, task: (progress: Progress, token: CancellationToken) => Thenable): Thenable { + private _withProgress(handle: number, task: (progress: Progress, token: CancellationToken) => Thenable): Thenable { const progress = { - report: (message: string) => { - this._proxy.$progressReport(handle, message); + report: (p: IProgressStep) => { + this._proxy.$progressReport(handle, p); } }; @@ -50,3 +47,4 @@ export class ExtHostProgress { return p; } } + diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index cbb9164d699..6900cbf1e1c 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -11,6 +11,7 @@ import { Position as EditorPosition } from 'vs/platform/editor/common/editor'; import { IDecorationOptions, EndOfLineSequence } from 'vs/editor/common/editorCommon'; import * as vscode from 'vscode'; import URI from 'vs/base/common/uri'; +import { ProgressLocation as MainProgressLocation } from 'vs/platform/progress/common/progress'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; import { IPosition } from "vs/editor/common/core/position"; import { IRange } from "vs/editor/common/core/range"; @@ -405,3 +406,12 @@ export namespace EndOfLine { } } +export namespace ProgressLocation { + export function from(loc: vscode.ProgressLocation): MainProgressLocation { + switch (loc) { + case types.ProgressLocation.Scm: return MainProgressLocation.Scm; + case types.ProgressLocation.Window: return MainProgressLocation.Window; + } + return undefined; + } +} diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index a49e6c80e3c..323e4e304a9 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -1266,3 +1266,8 @@ export class ShellTask extends BaseTask { this._options = value; } } + +export enum ProgressLocation { + Scm = 1, + Window = 10, +} diff --git a/src/vs/workbench/api/node/mainThreadProgress.ts b/src/vs/workbench/api/node/mainThreadProgress.ts index 10f91b4720f..e7031b47d44 100644 --- a/src/vs/workbench/api/node/mainThreadProgress.ts +++ b/src/vs/workbench/api/node/mainThreadProgress.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { IProgressService2, IProgress } from 'vs/platform/progress/common/progress'; +import { IProgressService2, IProgress, IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress'; import { TPromise } from 'vs/base/common/winjs.base'; import { MainThreadProgressShape } from './extHost.protocol'; export class MainThreadProgress extends MainThreadProgressShape { private _progressService: IProgressService2; - private progress = new Map }>(); + private progress = new Map }>(); constructor( @IProgressService2 progressService: IProgressService2 @@ -20,26 +20,12 @@ export class MainThreadProgress extends MainThreadProgressShape { this._progressService = progressService; } - - $startWindow(handle: number, title: string): void { + $startProgress(handle: number, options: IProgressOptions): void { const task = this._createTask(handle); - this._progressService.withWindowProgress(title, task); + this._progressService.withProgress(options, task); } - $startScm(handle: number): void { - const task = this._createTask(handle); - this._progressService.withViewletProgress('workbench.view.scm', task); - } - - private _createTask(handle: number) { - return (progress: IProgress) => { - return new TPromise(resolve => { - this.progress.set(handle, { resolve, progress }); - }); - }; - } - - $progressReport(handle: number, message: any): void { + $progressReport(handle: number, message: IProgressStep): void { this.progress.get(handle).progress.report(message); } @@ -47,4 +33,12 @@ export class MainThreadProgress extends MainThreadProgressShape { this.progress.get(handle).resolve(); this.progress.delete(handle); } + + private _createTask(handle: number) { + return (progress: IProgress) => { + return new TPromise(resolve => { + this.progress.set(handle, { resolve, progress }); + }); + }; + } } diff --git a/src/vs/workbench/services/progress/browser/progressService2.ts b/src/vs/workbench/services/progress/browser/progressService2.ts index db32d3e520b..b0bbda4b54d 100644 --- a/src/vs/workbench/services/progress/browser/progressService2.ts +++ b/src/vs/workbench/services/progress/browser/progressService2.ts @@ -8,7 +8,7 @@ import 'vs/css!vs/workbench/services/progress/browser/media/progressService2'; import * as dom from 'vs/base/browser/dom'; import { IActivityBarService, ProgressBadge } from 'vs/workbench/services/activity/common/activityBarService'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { IProgressService2, IProgress, Progress, emptyProgress } from 'vs/platform/progress/common/progress'; +import { IProgressService2, IProgressOptions, ProgressLocation, IProgress, Progress, emptyProgress } from 'vs/platform/progress/common/progress'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; import { Registry } from 'vs/platform/platform'; @@ -67,35 +67,50 @@ export class ProgressService2 implements IProgressService2 { // } - withWindowProgress(title: string, callback: (progress: IProgress) => TPromise): void { + withProgress(options: IProgressOptions, task: (progress: IProgress<{ message?: string, percentage?: number }>) => TPromise): void { + const { location } = options; + switch (location) { + case ProgressLocation.Window: + this._withWindowProgress(options, task); + break; + case ProgressLocation.Scm: + this._withViewletProgress('workbench.view.scm', task); + break; + default: + console.warn(`Bad progress location: ${location}`); + } + } + + + private _withWindowProgress(options: IProgressOptions, callback: (progress: IProgress<{ message?: string, percentage?: number }>) => TPromise): void { const task = { - progress: new Progress(() => this._updateProgress()), - title + progress: new Progress(() => this._updateWindowProgress()), + title: options.title }; const promise = callback(task.progress); this._stack.unshift(task); - this._updateProgress(); + this._updateWindowProgress(); always(promise, () => { const idx = this._stack.indexOf(task); this._stack.splice(idx, 1); - this._updateProgress(); + this._updateWindowProgress(); }); } - private _updateProgress() { + private _updateWindowProgress() { if (this._stack.length === 0) { WindowProgressItem.Instance.hide(); } else { const { title, progress } = this._stack[0]; - WindowProgressItem.Instance.text = progress.value || title; + WindowProgressItem.Instance.text = progress.value || title || ''; WindowProgressItem.Instance.show(); } } - withViewletProgress(viewletId: string, task: (progress: IProgress) => TPromise): void { + private _withViewletProgress(viewletId: string, task: (progress: IProgress) => TPromise): void { const promise = task(emptyProgress);