From 8932f62afac9b07b143e4935ed0f4de7deebe739 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 25 Sep 2020 15:59:15 +0200 Subject: [PATCH] adress API feedback https://github.com/microsoft/vscode/issues/54938 --- extensions/git/src/decorationProvider.ts | 36 +++++++++---------- extensions/git/src/repository.ts | 10 +++--- src/vs/vscode.proposed.d.ts | 34 ++++++++---------- .../workbench/api/common/extHost.api.impl.ts | 4 +-- .../api/common/extHostDecorations.ts | 14 ++++---- src/vs/workbench/api/common/extHostTypes.ts | 21 +++++++---- .../browser/api/extHostDecorations.test.ts | 10 +++--- 7 files changed, 65 insertions(+), 64 deletions(-) diff --git a/extensions/git/src/decorationProvider.ts b/extensions/git/src/decorationProvider.ts index ab6e5713e11..a61dd720caf 100644 --- a/extensions/git/src/decorationProvider.ts +++ b/extensions/git/src/decorationProvider.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { window, workspace, Uri, Disposable, Event, EventEmitter, Decoration, DecorationProvider, ThemeColor } from 'vscode'; +import { window, workspace, Uri, Disposable, Event, EventEmitter, FileDecoration, FileDecorationProvider, ThemeColor } from 'vscode'; import * as path from 'path'; import { Repository, GitResourceGroup } from './repository'; import { Model } from './model'; @@ -11,16 +11,16 @@ import { debounce } from './decorators'; import { filterEvent, dispose, anyEvent, fireEvent, PromiseSource } from './util'; import { GitErrorCodes, Status } from './api/git'; -class GitIgnoreDecorationProvider implements DecorationProvider { +class GitIgnoreDecorationProvider implements FileDecorationProvider { - private static Decoration: Decoration = { priority: 3, color: new ThemeColor('gitDecoration.ignoredResourceForeground') }; + private static Decoration: FileDecoration = { priority: 3, color: new ThemeColor('gitDecoration.ignoredResourceForeground') }; - readonly onDidChangeDecorations: Event; - private queue = new Map>; }>(); + readonly onDidChange: Event; + private queue = new Map>; }>(); private disposables: Disposable[] = []; constructor(private model: Model) { - this.onDidChangeDecorations = fireEvent(anyEvent( + this.onDidChange = fireEvent(anyEvent( filterEvent(workspace.onDidSaveTextDocument, e => /\.gitignore$|\.git\/info\/exclude$/.test(e.uri.path)), model.onDidOpenRepository, model.onDidCloseRepository @@ -29,7 +29,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider { this.disposables.push(window.registerDecorationProvider(this)); } - async provideDecoration(uri: Uri): Promise { + async provideFileDecoration(uri: Uri): Promise { const repository = this.model.getRepository(uri); if (!repository) { @@ -39,7 +39,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider { let queueItem = this.queue.get(repository.root); if (!queueItem) { - queueItem = { repository, queue: new Map>() }; + queueItem = { repository, queue: new Map>() }; this.queue.set(repository.root, queueItem); } @@ -84,19 +84,19 @@ class GitIgnoreDecorationProvider implements DecorationProvider { } } -class GitDecorationProvider implements DecorationProvider { +class GitDecorationProvider implements FileDecorationProvider { - private static SubmoduleDecorationData: Decoration = { - title: 'Submodule', - letter: 'S', + private static SubmoduleDecorationData: FileDecoration = { + tooltip: 'Submodule', + badge: 'S', color: new ThemeColor('gitDecoration.submoduleResourceForeground') }; private readonly _onDidChangeDecorations = new EventEmitter(); - readonly onDidChangeDecorations: Event = this._onDidChangeDecorations.event; + readonly onDidChange: Event = this._onDidChangeDecorations.event; private disposables: Disposable[] = []; - private decorations = new Map(); + private decorations = new Map(); constructor(private repository: Repository) { this.disposables.push( @@ -106,7 +106,7 @@ class GitDecorationProvider implements DecorationProvider { } private onDidRunGitStatus(): void { - let newDecorations = new Map(); + let newDecorations = new Map(); this.collectSubmoduleDecorationData(newDecorations); this.collectDecorationData(this.repository.indexGroup, newDecorations); @@ -119,7 +119,7 @@ class GitDecorationProvider implements DecorationProvider { this._onDidChangeDecorations.fire([...uris.values()].map(value => Uri.parse(value, true))); } - private collectDecorationData(group: GitResourceGroup, bucket: Map): void { + private collectDecorationData(group: GitResourceGroup, bucket: Map): void { for (const r of group.resourceStates) { const decoration = r.resourceDecoration; @@ -134,13 +134,13 @@ class GitDecorationProvider implements DecorationProvider { } } - private collectSubmoduleDecorationData(bucket: Map): void { + private collectSubmoduleDecorationData(bucket: Map): void { for (const submodule of this.repository.submodules) { bucket.set(Uri.file(path.join(this.repository.root, submodule.path)).toString(), GitDecorationProvider.SubmoduleDecorationData); } } - provideDecoration(uri: Uri): Decoration | undefined { + provideFileDecoration(uri: Uri): FileDecoration | undefined { return this.decorations.get(uri.toString()); } diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index f5e8a5ccfb3..ab32edbff66 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -5,7 +5,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, Decoration } from 'vscode'; +import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration } from 'vscode'; import * as nls from 'vscode-nls'; import { Branch, Change, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions, BranchQuery } from './api/git'; import { AutoFetcher } from './autofetch'; @@ -253,11 +253,11 @@ export class Resource implements SourceControlResourceState { } } - get resourceDecoration(): Decoration { + get resourceDecoration(): FileDecoration { return { - bubble: this.type !== Status.DELETED && this.type !== Status.INDEX_DELETED, - title: this.tooltip, - letter: this.letter, + propagte: this.type !== Status.DELETED && this.type !== Status.INDEX_DELETED, + tooltip: this.tooltip, + badge: this.letter, color: this.color, priority: this.priority }; diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index ae1b9cd29ed..22067ae3967 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -717,23 +717,18 @@ declare module 'vscode' { //#region file-decorations: https://github.com/microsoft/vscode/issues/54938 - // TODO@jrieken FileDecoration, FileDecorationProvider etc. - // TODO@jrieken Add selector notion to limit decorations to a view. - // TODO@jrieken Rename `Decoration.letter` to `short` so that it could be used for coverage et al. // TODO@jrieken priority -> DecorationSeverity.INFO,WARN,ERROR - // TODO@jrieken title -> tooltip - // TODO@jrieken bubble -> propagte - export class Decoration { + export class FileDecoration { /** - * A letter that represents this decoration. + * A very short string that represents this decoration. */ - letter?: string; + badge?: string; /** - * The human-readable title for this decoration. + * A human-readable tooltip for this decoration. */ - title?: string; + tooltip?: string; /** * The color of this decoration. @@ -747,46 +742,45 @@ declare module 'vscode' { /** * A flag expressing that this decoration should be - * propagted to its parents. + * propagated to its parents. */ - bubble?: boolean; + propagte?: boolean; /** * Creates a new decoration. * - * @param letter A letter that represents the decoration. - * @param title The title of the decoration. + * @param badge A letter that represents the decoration. + * @param tooltip The tooltip of the decoration. * @param color The color of the decoration. */ - constructor(letter?: string, title?: string, color?: ThemeColor); + constructor(badge?: string, tooltip?: string, color?: ThemeColor); } /** * The decoration provider interfaces defines the contract between extensions and * file decorations. */ - export interface DecorationProvider { + export interface FileDecorationProvider { /** * An event to signal decorations for one or many files have changed. * * @see [EventEmitter](#EventEmitter */ - onDidChangeDecorations: Event; + onDidChange: Event; /** * Provide decorations for a given uri. * - * * @param uri The uri of the file to provide a decoration for. * @param token A cancellation token. * @returns A decoration or a thenable that resolves to such. */ - provideDecoration(uri: Uri, token: CancellationToken): ProviderResult; + provideFileDecoration(uri: Uri, token: CancellationToken): ProviderResult; } export namespace window { - export function registerDecorationProvider(provider: DecorationProvider): Disposable; + export function registerDecorationProvider(provider: FileDecorationProvider): Disposable; } //#endregion diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 000b8a27af5..7917c012359 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -605,7 +605,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I registerCustomEditorProvider: (viewType: string, provider: vscode.CustomTextEditorProvider | vscode.CustomReadonlyEditorProvider, options: { webviewOptions?: vscode.WebviewPanelOptions, supportsMultipleEditorsPerDocument?: boolean } = {}) => { return extHostCustomEditors.registerCustomEditorProvider(extension, viewType, provider, options); }, - registerDecorationProvider(provider: vscode.DecorationProvider) { + registerDecorationProvider(provider: vscode.FileDecorationProvider) { checkProposedApiEnabled(extension); return extHostDecorations.registerDecorationProvider(provider, extension.identifier); }, @@ -1138,7 +1138,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I CallHierarchyItem: extHostTypes.CallHierarchyItem, DebugConsoleMode: extHostTypes.DebugConsoleMode, DebugConfigurationProviderTriggerKind: extHostTypes.DebugConfigurationProviderTriggerKind, - Decoration: extHostTypes.Decoration, + FileDecoration: extHostTypes.FileDecoration, UIKind: UIKind, ColorThemeKind: extHostTypes.ColorThemeKind, TimelineItem: extHostTypes.TimelineItem, diff --git a/src/vs/workbench/api/common/extHostDecorations.ts b/src/vs/workbench/api/common/extHostDecorations.ts index 3e52bbcc3aa..ddc119d1842 100644 --- a/src/vs/workbench/api/common/extHostDecorations.ts +++ b/src/vs/workbench/api/common/extHostDecorations.ts @@ -6,7 +6,7 @@ import type * as vscode from 'vscode'; import { URI } from 'vs/base/common/uri'; import { MainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/common/extHost.protocol'; -import { Disposable, Decoration } from 'vs/workbench/api/common/extHostTypes'; +import { Disposable, FileDecoration } from 'vs/workbench/api/common/extHostTypes'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; @@ -15,7 +15,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { asArray } from 'vs/base/common/arrays'; interface ProviderData { - provider: vscode.DecorationProvider; + provider: vscode.FileDecorationProvider; extensionId: ExtensionIdentifier; } @@ -34,12 +34,12 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { this._proxy = extHostRpc.getProxy(MainContext.MainThreadDecorations); } - registerDecorationProvider(provider: vscode.DecorationProvider, extensionId: ExtensionIdentifier): vscode.Disposable { + registerDecorationProvider(provider: vscode.FileDecorationProvider, extensionId: ExtensionIdentifier): vscode.Disposable { const handle = ExtHostDecorations._handlePool++; this._provider.set(handle, { provider, extensionId }); this._proxy.$registerDecorationProvider(handle, extensionId.value); - const listener = provider.onDidChangeDecorations(e => { + const listener = provider.onDidChange(e => { this._proxy.$onDidChange(handle, !e || (Array.isArray(e) && e.length > 250) ? null : asArray(e)); @@ -65,13 +65,13 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { await Promise.all(requests.map(async request => { try { const { uri, id } = request; - const data = await Promise.resolve(provider.provideDecoration(URI.revive(uri), token)); + const data = await Promise.resolve(provider.provideFileDecoration(URI.revive(uri), token)); if (!data) { return; } try { - Decoration.validate(data); - result[id] = [data.priority, data.bubble, data.title, data.letter, data.color]; + FileDecoration.validate(data); + result[id] = [data.priority, data.propagte, data.tooltip, data.badge, data.color]; } catch (e) { this._logService.warn(`INVALID decoration from extension '${extensionId.value}': ${e}`); } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 1497c19da9c..3ba9bc36d3c 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2729,22 +2729,29 @@ export enum ExtensionKind { Workspace = 2 } -export class Decoration { +export class FileDecoration { - static validate(d: Decoration): void { - if (d.letter && d.letter.length !== 1) { + static validate(d: FileDecoration): void { + if (d.badge && d.badge.length !== 1) { throw new Error(`The 'letter'-property must be undefined or a single character`); } - if (!d.bubble && !d.color && !d.letter && !d.priority && !d.title) { + if (!d.color && !d.badge && !d.tooltip) { throw new Error(`The decoration is empty`); } } - letter?: string; - title?: string; + badge?: string; + tooltip?: string; color?: vscode.ThemeColor; priority?: number; - bubble?: boolean; + propagate?: boolean; + + + constructor(badge?: string, tooltip?: string, color?: ThemeColor) { + this.badge = badge; + this.tooltip = tooltip; + this.color = color; + } } //#region Theming diff --git a/src/vs/workbench/test/browser/api/extHostDecorations.test.ts b/src/vs/workbench/test/browser/api/extHostDecorations.test.ts index 073006e636d..d086c14226e 100644 --- a/src/vs/workbench/test/browser/api/extHostDecorations.test.ts +++ b/src/vs/workbench/test/browser/api/extHostDecorations.test.ts @@ -48,8 +48,8 @@ suite('ExtHostDecorations', function () { // never returns extHostDecorations.registerDecorationProvider({ - onDidChangeDecorations: Event.None, - provideDecoration() { + onDidChange: Event.None, + provideFileDecoration() { calledA = true; return new Promise(() => { }); } @@ -57,10 +57,10 @@ suite('ExtHostDecorations', function () { // always returns extHostDecorations.registerDecorationProvider({ - onDidChangeDecorations: Event.None, - provideDecoration() { + onDidChange: Event.None, + provideFileDecoration() { calledB = true; - return new Promise(resolve => resolve({ letter: 'H', title: 'Hello' })); + return new Promise(resolve => resolve({ badge: 'H', tooltip: 'Hello' })); } }, nullExtensionDescription.identifier); -- GitLab