Separate quick diff API from SCM (#170544)

* Separate quick diff API from SCM
Part 1: split up the API.
upcoming in part 2: In editor UX for multiple quick diffs.
Fixes #169012

* Respond to review feedback

Co-authored-by: João Moreno <joao.moreno@microsoft.com>
This commit is contained in:
Alex Ross 2023-01-12 11:19:41 +01:00 committed by GitHub
parent 6d40104789
commit 04f0fb46ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 255 additions and 42 deletions

View file

@ -45,6 +45,7 @@ import './mainThreadLogService';
import './mainThreadMessageService';
import './mainThreadOutputService';
import './mainThreadProgress';
import './mainThreadQuickDiff';
import './mainThreadQuickOpen';
import './mainThreadRemoteConnectionData';
import './mainThreadSaveParticipant';

View file

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ExtHostContext, ExtHostQuickDiffShape, MainContext, MainThreadQuickDiffShape } from 'vs/workbench/api/common/extHost.protocol';
import { IQuickDiffService, QuickDiffProvider } from 'vs/workbench/contrib/scm/common/quickDiff';
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
@extHostNamedCustomer(MainContext.MainThreadQuickDiff)
export class MainThreadQuickDiff implements MainThreadQuickDiffShape {
private readonly proxy: ExtHostQuickDiffShape;
private providers = new Map<number, QuickDiffProvider>();
private providerDisposables = new Map<number, IDisposable>();
constructor(
extHostContext: IExtHostContext,
@IQuickDiffService private readonly quickDiffService: IQuickDiffService
) {
this.proxy = extHostContext.getProxy(ExtHostContext.ExtHostQuickDiff);
}
async $registerQuickDiffProvider(handle: number, label: string, rootUri: UriComponents | undefined): Promise<void> {
const provider: QuickDiffProvider = {
label,
rootUri: URI.revive(rootUri),
getOriginalResource: async (uri: URI) => {
return URI.revive(await this.proxy.$provideOriginalResource(handle, uri, new CancellationTokenSource().token));
}
};
this.providers.set(handle, provider);
const disposable = this.quickDiffService.addQuickDiffProvider(provider);
this.providerDisposables.set(handle, disposable);
}
async $unregisterQuickDiffProvider(handle: number): Promise<void> {
if (this.providers.has(handle)) {
this.providers.delete(handle);
}
if (this.providerDisposables.has(handle)) {
this.providerDisposables.delete(handle);
}
}
dispose(): void {
this.providers.clear();
dispose(this.providerDisposables.values());
this.providerDisposables.clear();
}
}

View file

@ -15,6 +15,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { MarshalledId } from 'vs/base/common/marshallingIds';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { IQuickDiffService, QuickDiffProvider } from 'vs/workbench/contrib/scm/common/quickDiff';
class MainThreadSCMResourceGroup implements ISCMResourceGroup {
@ -89,7 +90,7 @@ class MainThreadSCMResource implements ISCMResource {
}
}
class MainThreadSCMProvider implements ISCMProvider {
class MainThreadSCMProvider implements ISCMProvider, QuickDiffProvider {
private static ID_HANDLE = 0;
private _id = `scm${MainThreadSCMProvider.ID_HANDLE++}`;
@ -133,12 +134,15 @@ class MainThreadSCMProvider implements ISCMProvider {
private readonly _onDidChange = new Emitter<void>();
readonly onDidChange: Event<void> = this._onDidChange.event;
private _quickDiff: IDisposable | undefined;
constructor(
private readonly proxy: ExtHostSCMShape,
private readonly _handle: number,
private readonly _contextValue: string,
private readonly _label: string,
private readonly _rootUri: URI | undefined
private readonly _rootUri: URI | undefined,
private readonly _quickDiffService: IQuickDiffService
) { }
$updateSourceControl(features: SCMProviderFeatures): void {
@ -152,6 +156,13 @@ class MainThreadSCMProvider implements ISCMProvider {
if (typeof features.statusBarCommands !== 'undefined') {
this._onDidChangeStatusBarCommands.fire(this.statusBarCommands!);
}
if (features.hasQuickDiffProvider && !this._quickDiff) {
this._quickDiff = this._quickDiffService.addQuickDiffProvider(this);
} else if (features.hasQuickDiffProvider === false && this._quickDiff) {
this._quickDiff.dispose();
this._quickDiff = undefined;
}
}
$registerGroups(_groups: [number /*handle*/, string /*id*/, string /*label*/, SCMGroupFeatures][]): void {
@ -284,7 +295,8 @@ export class MainThreadSCM implements MainThreadSCMShape {
constructor(
extHostContext: IExtHostContext,
@ISCMService private readonly scmService: ISCMService,
@ISCMViewService private readonly scmViewService: ISCMViewService
@ISCMViewService private readonly scmViewService: ISCMViewService,
@IQuickDiffService private readonly quickDiffService: IQuickDiffService
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostSCM);
}
@ -300,7 +312,7 @@ export class MainThreadSCM implements MainThreadSCMShape {
}
$registerSourceControl(handle: number, id: string, label: string, rootUri: UriComponents | undefined): void {
const provider = new MainThreadSCMProvider(this._proxy, handle, id, label, rootUri ? URI.revive(rootUri) : undefined);
const provider = new MainThreadSCMProvider(this._proxy, handle, id, label, rootUri ? URI.revive(rootUri) : undefined, this.quickDiffService);
const repository = this.scmService.registerSCMProvider(provider);
this._repositories.set(handle, repository);

View file

@ -96,6 +96,7 @@ import { DebugConfigurationProviderTriggerKind } from 'vs/workbench/contrib/debu
import { IExtHostLocalizationService } from 'vs/workbench/api/common/extHostLocalizationService';
import { EditSessionIdentityMatch } from 'vs/platform/workspace/common/editSessions';
import { ExtHostProfileContentHandlers } from 'vs/workbench/api/common/extHostProfileContentHandler';
import { ExtHostQuickDiff } from 'vs/workbench/api/common/extHostQuickDiff';
export interface IExtensionRegistries {
mine: ExtensionDescriptionRegistry;
@ -175,6 +176,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostLogService, extHostDocumentsAndEditors));
const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, createExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands));
const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
const extHostQuickDiff = rpcProtocol.set(ExtHostContext.ExtHostQuickDiff, new ExtHostQuickDiff(rpcProtocol));
const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, createExtHostComments(rpcProtocol, extHostCommands, extHostDocuments));
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol));
@ -802,6 +804,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension, 'profileContentHandlers');
return extHostProfileContentHandlers.registrProfileContentHandler(extension, id, handler);
},
async registerQuickDiffProvider(quickDiffProvider: vscode.QuickDiffProvider, label: string, rootUri?: vscode.Uri): Promise<vscode.Disposable> {
checkProposedApiEnabled(extension, 'quickDiffProvider');
return extHostQuickDiff.registerQuickDiffProvider(quickDiffProvider, label, rootUri);
},
get tabGroups(): vscode.TabGroups {
return extHostEditorTabs.tabGroups;
}

View file

@ -1237,6 +1237,11 @@ export interface MainThreadSCMShape extends IDisposable {
$setValidationProviderIsEnabled(sourceControlHandle: number, enabled: boolean): void;
}
export interface MainThreadQuickDiffShape extends IDisposable {
$registerQuickDiffProvider(handle: number, label: string, rootUri: UriComponents | undefined): Promise<void>;
$unregisterQuickDiffProvider(handle: number): Promise<void>;
}
export type DebugSessionUUID = string;
export interface IDebugConfiguration {
@ -1869,6 +1874,10 @@ export interface ExtHostSCMShape {
$setSelectedSourceControl(selectedSourceControlHandle: number | undefined): Promise<void>;
}
export interface ExtHostQuickDiffShape {
$provideOriginalResource(sourceControlHandle: number, uri: UriComponents, token: CancellationToken): Promise<UriComponents | null>;
}
export interface ExtHostTaskShape {
$provideTasks(handle: number, validTypes: { [key: string]: boolean }): Promise<tasks.ITaskSetDTO>;
$resolveTask(handle: number, taskDTO: tasks.ITaskDTO): Promise<tasks.ITaskDTO | undefined>;
@ -2333,6 +2342,7 @@ export const MainContext = {
MainThreadMessageService: createProxyIdentifier<MainThreadMessageServiceShape>('MainThreadMessageService'),
MainThreadOutputService: createProxyIdentifier<MainThreadOutputServiceShape>('MainThreadOutputService'),
MainThreadProgress: createProxyIdentifier<MainThreadProgressShape>('MainThreadProgress'),
MainThreadQuickDiff: createProxyIdentifier<MainThreadQuickDiffShape>('MainThreadQuickDiff'),
MainThreadQuickOpen: createProxyIdentifier<MainThreadQuickOpenShape>('MainThreadQuickOpen'),
MainThreadStatusBar: createProxyIdentifier<MainThreadStatusBarShape>('MainThreadStatusBar'),
MainThreadSecretState: createProxyIdentifier<MainThreadSecretStateShape>('MainThreadSecretState'),
@ -2385,6 +2395,7 @@ export const ExtHostContext = {
ExtHostLanguages: createProxyIdentifier<ExtHostLanguagesShape>('ExtHostLanguages'),
ExtHostLanguageFeatures: createProxyIdentifier<ExtHostLanguageFeaturesShape>('ExtHostLanguageFeatures'),
ExtHostQuickOpen: createProxyIdentifier<ExtHostQuickOpenShape>('ExtHostQuickOpen'),
ExtHostQuickDiff: createProxyIdentifier<ExtHostQuickDiffShape>('ExtHostQuickDiff'),
ExtHostExtensionService: createProxyIdentifier<ExtHostExtensionServiceShape>('ExtHostExtensionService'),
ExtHostLogLevelServiceShape: createProxyIdentifier<ExtHostLogLevelServiceShape>('ExtHostLogLevelServiceShape'),
ExtHostTerminalService: createProxyIdentifier<ExtHostTerminalServiceShape>('ExtHostTerminalService'),

View file

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import type * as vscode from 'vscode';
import { CancellationToken } from 'vs/base/common/cancellation';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ExtHostQuickDiffShape, IMainContext, MainContext, MainThreadQuickDiffShape } from 'vs/workbench/api/common/extHost.protocol';
import { asPromise } from 'vs/base/common/async';
export class ExtHostQuickDiff implements ExtHostQuickDiffShape {
private static handlePool: number = 0;
private proxy: MainThreadQuickDiffShape;
private providers: Map<number, vscode.QuickDiffProvider> = new Map();
constructor(
mainContext: IMainContext
) {
this.proxy = mainContext.getProxy(MainContext.MainThreadQuickDiff);
}
$provideOriginalResource(handle: number, uriComponents: UriComponents, token: CancellationToken): Promise<UriComponents | null> {
const uri = URI.revive(uriComponents);
const provider = this.providers.get(handle);
if (!provider) {
return Promise.resolve(null);
}
return asPromise(() => provider.provideOriginalResource!(uri, token))
.then<UriComponents | null>(r => r || null);
}
async registerQuickDiffProvider(quickDiffProvider: vscode.QuickDiffProvider, label: string, rootUri?: vscode.Uri): Promise<vscode.Disposable> {
const handle = ExtHostQuickDiff.handlePool++;
this.providers.set(handle, quickDiffProvider);
await this.proxy.$registerQuickDiffProvider(handle, label, rootUri);
return {
dispose: () => this.providers.delete(handle)
};
}
}

View file

@ -18,7 +18,7 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Progress } from 'vs/platform/progress/common/progress';
import { getOriginalResource } from 'vs/workbench/contrib/scm/browser/dirtydiffDecorator';
import { ISCMService } from 'vs/workbench/contrib/scm/common/scm';
import { IQuickDiffService } from 'vs/workbench/contrib/scm/common/quickDiff';
registerEditorAction(class FormatModifiedAction extends EditorAction {
@ -50,11 +50,11 @@ registerEditorAction(class FormatModifiedAction extends EditorAction {
export async function getModifiedRanges(accessor: ServicesAccessor, modified: ITextModel): Promise<Range[] | undefined | null> {
const scmService = accessor.get(ISCMService);
const quickDiffService = accessor.get(IQuickDiffService);
const workerService = accessor.get(IEditorWorkerService);
const modelService = accessor.get(ITextModelService);
const original = await getOriginalResource(scmService, modified.uri);
const original = await getOriginalResource(quickDiffService, modified.uri);
if (!original) {
return null; // let undefined signify no changes, null represents no source control (there's probably a better way, but I can't think of one rn)
}

View file

@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import 'vs/css!./media/dirtydiffDecorator';
import { ThrottledDelayer, first } from 'vs/base/common/async';
import { ThrottledDelayer } from 'vs/base/common/async';
import { IDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import * as ext from 'vs/workbench/common/contributions';
@ -15,7 +15,7 @@ import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/se
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { URI } from 'vs/base/common/uri';
import { ISCMService, ISCMRepository, ISCMProvider } from 'vs/workbench/contrib/scm/common/scm';
import { ISCMService, ISCMRepository } from 'vs/workbench/contrib/scm/common/scm';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
import { IColorTheme, themeColorFromId, IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService';
import { editorErrorForeground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry';
@ -34,7 +34,7 @@ import { IDiffEditorOptions, EditorOption } from 'vs/editor/common/config/editor
import { Action, IAction, ActionRunner } from 'vs/base/common/actions';
import { IActionBarOptions } from 'vs/base/browser/ui/actionbar/actionbar';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { basename, isEqualOrParent } from 'vs/base/common/resources';
import { basename } from 'vs/base/common/resources';
import { MenuId, IMenuService, IMenu, MenuItemAction, MenuRegistry } from 'vs/platform/actions/common/actions';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IEditorModel, ScrollType, IEditorContribution, IDiffEditorModel } from 'vs/editor/common/editorCommon';
@ -51,13 +51,13 @@ import { TextCompareEditorActiveContext } from 'vs/workbench/common/contextkeys'
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer';
import { Color } from 'vs/base/common/color';
import { Iterable } from 'vs/base/common/iterator';
import { ResourceMap } from 'vs/base/common/map';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IQuickDiffService } from 'vs/workbench/contrib/scm/common/quickDiff';
class DiffActionRunner extends ActionRunner {
@ -1095,37 +1095,10 @@ function compareChanges(a: IChange, b: IChange): number {
return a.originalEndLineNumber - b.originalEndLineNumber;
}
export function createProviderComparer(uri: URI): (a: ISCMProvider, b: ISCMProvider) => number {
return (a, b) => {
const aIsParent = isEqualOrParent(uri, a.rootUri!);
const bIsParent = isEqualOrParent(uri, b.rootUri!);
if (aIsParent && bIsParent) {
return a.rootUri!.fsPath.length - b.rootUri!.fsPath.length;
} else if (aIsParent) {
return -1;
} else if (bIsParent) {
return 1;
} else {
return 0;
}
};
}
export async function getOriginalResource(scmService: ISCMService, uri: URI): Promise<URI | null> {
const providers = Iterable.map(scmService.repositories, r => r.provider);
const rootedProviders = Array.from(Iterable.filter(providers, p => !!p.rootUri));
rootedProviders.sort(createProviderComparer(uri));
const result = await first(rootedProviders.map(p => () => p.getOriginalResource(uri)));
if (result) {
return result;
}
const nonRootedProviders = Iterable.filter(providers, p => !p.rootUri);
return first(Array.from(nonRootedProviders, p => () => p.getOriginalResource(uri)));
export async function getOriginalResource(quickDiffService: IQuickDiffService, uri: URI): Promise<URI | null> {
const quickDiffs = await quickDiffService.getQuickDiffs(uri);
return quickDiffs.length > 0 ? quickDiffs[0].originalResource : null;
}
export class DirtyDiffModel extends Disposable {
@ -1151,6 +1124,7 @@ export class DirtyDiffModel extends Disposable {
constructor(
textFileModel: IResolvedTextFileEditorModel,
@ISCMService private readonly scmService: ISCMService,
@IQuickDiffService private readonly quickDiffService: IQuickDiffService,
@IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@ITextModelService private readonly textModelResolverService: ITextModelService,
@ -1306,7 +1280,7 @@ export class DirtyDiffModel extends Disposable {
}
const uri = this._model.resource;
return getOriginalResource(this.scmService, uri);
return getOriginalResource(this.quickDiffService, uri);
}
findNextClosestChange(lineNumber: number, inclusive = true): number {

View file

@ -30,6 +30,8 @@ import { SCMRepositoriesViewPane } from 'vs/workbench/contrib/scm/browser/scmRep
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/suggest';
import { MANAGE_TRUST_COMMAND_ID, WorkspaceTrustContext } from 'vs/workbench/contrib/workspace/common/workspace';
import { IQuickDiffService } from 'vs/workbench/contrib/scm/common/quickDiff';
import { QuickDiffService } from 'vs/workbench/contrib/scm/common/quickDiffService';
ModesRegistry.registerLanguage({
id: 'scminput',
@ -385,3 +387,4 @@ MenuRegistry.appendMenuItem(MenuId.SCMSourceControl, {
registerSingleton(ISCMService, SCMService, InstantiationType.Delayed);
registerSingleton(ISCMViewService, SCMViewService, InstantiationType.Delayed);
registerSingleton(IQuickDiffService, QuickDiffService, InstantiationType.Delayed);

View file

@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IDisposable } from 'vs/base/common/lifecycle';
export const IQuickDiffService = createDecorator<IQuickDiffService>('quickDiff');
export interface QuickDiffProvider {
label: string;
rootUri: URI | undefined;
getOriginalResource(uri: URI): Promise<URI | null>;
}
export interface QuickDiff {
label: string;
originalResource: URI;
}
export interface IQuickDiffService {
readonly _serviceBrand: undefined;
addQuickDiffProvider(quickDiff: QuickDiffProvider): IDisposable;
getQuickDiffs(uri: URI): Promise<QuickDiff[]>;
}

View file

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IQuickDiffService, QuickDiff, QuickDiffProvider } from 'vs/workbench/contrib/scm/common/quickDiff';
import { isEqualOrParent } from 'vs/base/common/resources';
function createProviderComparer(uri: URI): (a: QuickDiffProvider, b: QuickDiffProvider) => number {
return (a, b) => {
if (a.rootUri && !b.rootUri) {
return -1;
} else if (!a.rootUri && b.rootUri) {
return 1;
} else if (!a.rootUri && !b.rootUri) {
return 0;
}
const aIsParent = isEqualOrParent(uri, a.rootUri!);
const bIsParent = isEqualOrParent(uri, b.rootUri!);
if (aIsParent && bIsParent) {
return a.rootUri!.fsPath.length - b.rootUri!.fsPath.length;
} else if (aIsParent) {
return -1;
} else if (bIsParent) {
return 1;
} else {
return 0;
}
};
}
export class QuickDiffService implements IQuickDiffService {
declare readonly _serviceBrand: undefined;
private quickDiffProviders: Set<QuickDiffProvider> = new Set();
addQuickDiffProvider(quickDiff: QuickDiffProvider): IDisposable {
this.quickDiffProviders.add(quickDiff);
return {
dispose: () => {
this.quickDiffProviders.delete(quickDiff);
}
};
}
private isQuickDiff(diff: { originalResource: URI | null; label: string }): diff is QuickDiff {
return !!diff.originalResource;
}
async getQuickDiffs(uri: URI): Promise<QuickDiff[]> {
const sorted = Array.from(this.quickDiffProviders).sort(createProviderComparer(uri));
const diffs = await Promise.all(Array.from(sorted.values()).map(async (provider) => {
const diff = {
originalResource: await provider.getOriginalResource(uri),
label: provider.label
};
return diff;
}));
return diffs.filter<QuickDiff>(this.isQuickDiff);
}
}

View file

@ -50,6 +50,7 @@ export const allApiProposals = Object.freeze({
notebookMime: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookMime.d.ts',
portsAttributes: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.portsAttributes.d.ts',
profileContentHandlers: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.profileContentHandlers.d.ts',
quickDiffProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.quickDiffProvider.d.ts',
quickPickSortByLabel: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts',
resolvers: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.resolvers.d.ts',
scmActionButton: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.scmActionButton.d.ts',

View file

@ -0,0 +1,13 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/169012
export namespace window {
export function registerQuickDiffProvider(quickDiffProvider: QuickDiffProvider, label: string, rootUri?: Uri): Thenable<Disposable>;
}
}