Merge from vscode 2cd495805cf99b31b6926f08ff4348124b2cf73d

This commit is contained in:
ADS Merger
2020-06-30 04:40:21 +00:00
committed by AzureDataStudio
parent a8a7559229
commit 1388493cc1
602 changed files with 16375 additions and 12940 deletions

View File

@@ -8,12 +8,13 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { localize } from 'vs/nls';
import { InstallRecommendedExtensionAction, ShowRecommendedExtensionsAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { InstallRecommendedExtensionAction, ShowRecommendedExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { ExtensionRecommendationSource, IExtensionRecommendationReson } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionsConfiguration, ConfigurationKey } from 'vs/workbench/contrib/extensions/common/extensions';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { IAction } from 'vs/base/common/actions';
type ExtensionRecommendationsNotificationClassification = {
userReaction: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
@@ -56,22 +57,27 @@ export abstract class ExtensionRecommendations extends Disposable {
return this._activationPromise;
}
private runAction(action: IAction) {
try {
action.run();
} finally {
action.dispose();
}
}
protected promptImportantExtensionInstallNotification(extensionId: string, message: string): void {
this.notificationService.prompt(Severity.Info, message,
[{
label: localize('install', 'Install'),
run: () => {
this.telemetryService.publicLog2<{ userReaction: string, extensionId: string }, ExtensionRecommendationsNotificationClassification>('extensionRecommendations:popup', { userReaction: 'install', extensionId });
this.instantiationService.createInstance(InstallRecommendedExtensionAction, extensionId).run();
this.runAction(this.instantiationService.createInstance(InstallRecommendedExtensionAction, extensionId));
}
}, {
label: localize('showRecommendations', "Show Recommendations"),
label: localize('moreInformation', "More Information"),
run: () => {
this.telemetryService.publicLog2<{ userReaction: string, extensionId: string }, ExtensionRecommendationsNotificationClassification>('extensionRecommendations:popup', { userReaction: 'show', extensionId });
const recommendationsAction = this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, localize('showRecommendations', "Show Recommendations"));
recommendationsAction.run();
recommendationsAction.dispose();
this.runAction(this.instantiationService.createInstance(ShowRecommendedExtensionAction, extensionId));
}
}, {
label: choiceNever,

View File

@@ -153,7 +153,7 @@ actionRegistry.registerWorkbenchAction(checkForUpdatesAction, `Extensions: Check
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(EnableAutoUpdateAction), `Extensions: Enable Auto Updating Extensions`, ExtensionsLabel);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(DisableAutoUpdateAction), `Extensions: Disable Auto Updating Extensions`, ExtensionsLabel);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(InstallSpecificVersionOfExtensionAction), 'Install Specific Version of Extension...', ExtensionsLabel);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ReinstallAction), 'Reinstall Extension...', localize('developer', "Developer"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ReinstallAction), 'Reinstall Extension...', localize({ key: 'developer', comment: ['A developer on Code itself or someone diagnosing issues in Code'] }, "Developer"));
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration)
.registerConfiguration({
@@ -202,6 +202,11 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration)
type: 'array',
description: localize('handleUriConfirmedExtensions', "When an extension is listed here, a confirmation prompt will not be shown when that extension handles a URI."),
default: []
},
'extensions.webWorker': {
type: 'boolean',
description: localize('extensionsWebWorker', "Enable web worker extension host."),
default: false
}
}
});
@@ -473,9 +478,10 @@ class ExtensionsContributions implements IWorkbenchContribution {
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService
) {
const canManageExtensions = extensionManagementServerService.localExtensionManagementServer || extensionManagementServerService.remoteExtensionManagementServer;
if (canManageExtensions) {
if (extensionManagementServerService.localExtensionManagementServer
|| extensionManagementServerService.remoteExtensionManagementServer
|| extensionManagementServerService.webExtensionManagementServer
) {
Registry.as<IQuickAccessRegistry>(Extensions.Quickaccess).registerQuickAccessProvider({
ctor: InstallExtensionQuickAccessProvider,
prefix: InstallExtensionQuickAccessProvider.PREFIX,

View File

@@ -26,7 +26,7 @@ import { Query } from 'vs/workbench/contrib/extensions/common/extensionQuery';
import { IFileService, IFileContent } from 'vs/platform/files/common/files';
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions';
import { URI } from 'vs/base/common/uri';
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -1280,7 +1280,7 @@ export class ReloadAction extends ExtensionAction {
const isUninstalled = this.extension.state === ExtensionState.Uninstalled;
const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension!.identifier))[0];
const isSameExtensionRunning = runningExtension && this.extension.server === this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation);
const isSameExtensionRunning = runningExtension && this.extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension));
if (isUninstalled) {
if (isSameExtensionRunning && !this.extensionService.canRemoveExtension(runningExtension)) {
@@ -1302,7 +1302,7 @@ export class ReloadAction extends ExtensionAction {
if (this.extensionService.canAddExtension(toExtensionDescription(this.extension.local))) {
return;
}
const runningExtensionServer = this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation);
const runningExtensionServer = this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension));
if (isSameExtensionRunning) {
// Different version of same extension is running. Requires reload to run the current version
@@ -1665,7 +1665,7 @@ export class ShowDisabledExtensionsAction extends Action {
export class ClearExtensionsInputAction extends Action {
static readonly ID = 'workbench.extensions.action.clearExtensionsInput';
static readonly LABEL = localize('clearExtensionsInput', "Clear Extensions Input");
static readonly LABEL = localize('clearExtensionsInput', "Clear Extensions Search Results");
constructor(
id: string,
@@ -1848,6 +1848,40 @@ export class InstallWorkspaceRecommendedExtensionsAction extends Action {
}
}
export class ShowRecommendedExtensionAction extends Action {
static readonly ID = 'workbench.extensions.action.showRecommendedExtension';
static readonly LABEL = localize('showRecommendedExtension', "Show Recommended Extension");
private extensionId: string;
constructor(
extensionId: string,
@IViewletService private readonly viewletService: IViewletService,
@IExtensionsWorkbenchService private readonly extensionWorkbenchService: IExtensionsWorkbenchService,
) {
super(InstallRecommendedExtensionAction.ID, InstallRecommendedExtensionAction.LABEL, undefined, false);
this.extensionId = extensionId;
}
run(): Promise<any> {
return this.viewletService.openViewlet(VIEWLET_ID, true)
.then(viewlet => viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer)
.then(viewlet => {
viewlet.search(`@id:${this.extensionId}`);
viewlet.focus();
return this.extensionWorkbenchService.queryGallery({ names: [this.extensionId], source: 'install-recommendation', pageSize: 1 }, CancellationToken.None)
.then(pager => {
if (pager && pager.firstPage && pager.firstPage.length) {
const extension = pager.firstPage[0];
return this.extensionWorkbenchService.open(extension);
}
return null;
});
});
}
}
export class InstallRecommendedExtensionAction extends Action {
static readonly ID = 'workbench.extensions.action.installRecommendedExtension';
@@ -1876,6 +1910,7 @@ export class InstallRecommendedExtensionAction extends Action {
if (pager && pager.firstPage && pager.firstPage.length) {
const extension = pager.firstPage[0];
return this.extensionWorkbenchService.install(extension)
.then(() => this.extensionWorkbenchService.open(extension))
.then(() => null, err => {
console.error(err);
return promptDownloadManually(extension.gallery, localize('failedToInstall', "Failed to install \'{0}\'.", extension.identifier.id), err, this.instantiationService);
@@ -2612,7 +2647,7 @@ export class StatusLabelAction extends Action implements IExtensionContainer {
};
const canRemoveExtension = () => {
if (this.extension!.local) {
if (runningExtensions.every(e => !(areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension!.identifier) && this.extension!.server === this.extensionManagementServerService.getExtensionManagementServer(e.extensionLocation)))) {
if (runningExtensions.every(e => !(areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension!.identifier) && this.extension!.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(e))))) {
return true;
}
return this.extensionService.canRemoveExtension(toExtensionDescription(this.extension!.local));
@@ -2657,7 +2692,7 @@ export class MaliciousStatusLabelAction extends ExtensionAction {
constructor(long: boolean) {
const tooltip = localize('malicious tooltip', "This extension was reported to be problematic.");
const label = long ? tooltip : localize('malicious', "Malicious");
const label = long ? tooltip : localize({ key: 'malicious', comment: ['Refers to a malicious extension'] }, "Malicious");
super('extensions.install', label, '', false);
this.tooltip = localize('malicious tooltip', "This extension was reported to be problematic.");
}
@@ -2844,7 +2879,7 @@ export class SystemDisabledWarningAction extends ExtensionAction {
}
if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {
const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension!.identifier))[0];
const runningExtensionServer = runningExtension ? this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation) : null;
const runningExtensionServer = runningExtension ? this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)) : null;
if (this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
if (prefersExecuteOnWorkspace(this.extension.local!.manifest, this.productService, this.configurationService)) {
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;

View File

@@ -16,8 +16,8 @@ import { domEvent } from 'vs/base/browser/event';
import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction, SyncIgnoredIconAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { Label, RatingsWidget, /*InstallCountWidget, */RecommendationWidget, RemoteBadgeWidget, TooltipWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { Label, RatingsWidget, /*InstallCountWidget,*/ RecommendationWidget, RemoteBadgeWidget, TooltipWidget, ExtensionPackCountWidget as ExtensionPackBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
@@ -167,7 +167,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
isDisabled = false;
if (extension.local && !isLanguagePackExtension(extension.local.manifest)) {
const runningExtension = runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, extension.identifier))[0];
isDisabled = !(runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation));
isDisabled = !(runningExtension && extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)));
}
toggleClass(data.root, 'disabled', isDisabled);
};

View File

@@ -199,19 +199,19 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
const getOutdatedViewName = (): string => getViewName(localize('outdated', "Outdated"), server);
const onDidChangeServerLabel: EventOf<void> = EventOf.map(this.labelService.onDidChangeFormatters, () => undefined);
return [{
id: `extensions.${server.authority}.installed`,
id: `extensions.${server.id}.installed`,
get name() { return getInstalledViewName(); },
ctorDescriptor: new SyncDescriptor(ServerExtensionsView, [server, EventOf.map<void, string>(onDidChangeServerLabel, () => getInstalledViewName())]),
when: ContextKeyExpr.and(ContextKeyExpr.has('searchInstalledExtensions')),
weight: 100
}, {
id: `extensions.${server.authority}.outdated`,
id: `extensions.${server.id}.outdated`,
get name() { return getOutdatedViewName(); },
ctorDescriptor: new SyncDescriptor(ServerExtensionsView, [server, EventOf.map<void, string>(onDidChangeServerLabel, () => getOutdatedViewName())]),
when: ContextKeyExpr.and(ContextKeyExpr.has('searchOutdatedExtensions')),
weight: 100
}, {
id: `extensions.${server.authority}.default`,
id: `extensions.${server.id}.default`,
get name() { return getInstalledViewName(); },
ctorDescriptor: new SyncDescriptor(ServerExtensionsView, [server, EventOf.map<void, string>(onDidChangeServerLabel, () => getInstalledViewName())]),
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), RemoteNameContext.notEqualsTo('')),

View File

@@ -19,7 +19,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { Delegate, Renderer, IExtensionsViewState } from 'vs/workbench/contrib/extensions/browser/extensionsList';
import { IExtension, IExtensionsWorkbenchService, ExtensionState } from 'vs/workbench/contrib/extensions/common/extensions';
import { Query } from 'vs/workbench/contrib/extensions/common/extensionQuery';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
@@ -373,9 +373,9 @@ export class ExtensionsListView extends ViewPane {
const runningExtensionsById = runningExtensions.reduce((result, e) => { result.set(ExtensionIdentifier.toKey(e.identifier.value), e); return result; }, new Map<string, IExtensionDescription>());
result = result.sort((e1, e2) => {
const running1 = runningExtensionsById.get(ExtensionIdentifier.toKey(e1.identifier.id));
const isE1Running = running1 && this.extensionManagementServerService.getExtensionManagementServer(running1.extensionLocation) === e1.server;
const isE1Running = running1 && this.extensionManagementServerService.getExtensionManagementServer(toExtension(running1)) === e1.server;
const running2 = runningExtensionsById.get(ExtensionIdentifier.toKey(e2.identifier.id));
const isE2Running = running2 && this.extensionManagementServerService.getExtensionManagementServer(running2.extensionLocation) === e2.server;
const isE2Running = running2 && this.extensionManagementServerService.getExtensionManagementServer(toExtension(running2)) === e2.server;
if ((isE1Running && isE2Running)) {
return e1.displayName.localeCompare(e2.displayName);
}

View File

@@ -39,6 +39,7 @@ import { IModeService } from 'vs/editor/common/services/modeService';
import { IProductService } from 'vs/platform/product/common/productService';
import { asDomUri } from 'vs/base/browser/dom';
import { getIgnoredExtensions } from 'vs/platform/userDataSync/common/extensionsMerge';
import { isWeb } from 'vs/base/common/platform';
import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator'; // {{SQL CARBON EDIT}}
import { IOpenerService } from 'vs/platform/opener/common/opener'; // {{SQL CARBON EDIT}}
@@ -508,6 +509,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
private readonly localExtensions: Extensions | null = null;
private readonly remoteExtensions: Extensions | null = null;
private readonly webExtensions: Extensions | null = null;
private syncDelayer: ThrottledDelayer<void>;
private autoUpdateDelayer: ThrottledDelayer<void>;
@@ -543,6 +545,10 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
this.remoteExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.remoteExtensionManagementServer, ext => this.getExtensionState(ext)));
this._register(this.remoteExtensions.onChange(e => this._onChange.fire(e ? e.extension : undefined)));
}
if (extensionManagementServerService.webExtensionManagementServer) {
this.webExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.webExtensionManagementServer, ext => this.getExtensionState(ext)));
this._register(this.webExtensions.onChange(e => this._onChange.fire(e ? e.extension : undefined)));
}
this.syncDelayer = new ThrottledDelayer<void>(ExtensionsWorkbenchService.SyncPeriod);
this.autoUpdateDelayer = new ThrottledDelayer<void>(1000);
@@ -584,6 +590,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (this.remoteExtensions) {
result.push(...this.remoteExtensions.local);
}
if (this.webExtensions) {
result.push(...this.webExtensions.local);
}
return result;
}
@@ -595,6 +604,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (this.remoteExtensions) {
allLocal.push(...this.remoteExtensions.local);
}
if (this.webExtensions) {
allLocal.push(...this.webExtensions.local);
}
return allLocal.filter(e => e.outdated && e.local && e.state === ExtensionState.Installed);
}
@@ -606,6 +618,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (this.remoteExtensions && this.extensionManagementServerService.remoteExtensionManagementServer === server) {
return this.remoteExtensions.queryInstalled();
}
if (this.webExtensions && this.extensionManagementServerService.webExtensionManagementServer === server) {
return this.webExtensions.queryInstalled();
}
}
if (this.localExtensions) {
@@ -614,6 +629,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (this.remoteExtensions) {
await this.remoteExtensions.queryInstalled();
}
if (this.webExtensions) {
await this.webExtensions.queryInstalled();
}
return this.local;
}
@@ -668,18 +686,21 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (extensions.length === 1) {
return extensions[0];
}
const pickRemoteOrFirstExtension = (from: IExtension[]): IExtension => {
const remoteExtension = from.filter(e => e.server === this.extensionManagementServerService.remoteExtensionManagementServer)[0];
return remoteExtension ? remoteExtension : from[0];
};
const enabledExtensions = extensions.filter(e => e.local && this.extensionEnablementService.isEnabled(e.local));
return enabledExtensions.length === 1 ? enabledExtensions[0] : pickRemoteOrFirstExtension(extensions);
if (enabledExtensions.length === 0) {
return extensions[0];
}
if (enabledExtensions.length === 1) {
return enabledExtensions[0];
}
return enabledExtensions.find(e => e.server === this.extensionManagementServerService.remoteExtensionManagementServer) || enabledExtensions[0];
}
private fromGallery(gallery: IGalleryExtension, maliciousExtensionSet: Set<string>): IExtension {
Promise.all([
this.localExtensions ? this.localExtensions.syncLocalWithGalleryExtension(gallery, maliciousExtensionSet) : Promise.resolve(false),
this.remoteExtensions ? this.remoteExtensions.syncLocalWithGalleryExtension(gallery, maliciousExtensionSet) : Promise.resolve(false)
this.remoteExtensions ? this.remoteExtensions.syncLocalWithGalleryExtension(gallery, maliciousExtensionSet) : Promise.resolve(false),
this.webExtensions ? this.webExtensions.syncLocalWithGalleryExtension(gallery, maliciousExtensionSet) : Promise.resolve(false)
])
.then(result => {
if (result[0] || result[1]) {
@@ -716,7 +737,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
private getExtensionState(extension: Extension): ExtensionState {
const isInstalling = this.installing.some(i => areSameExtensions(i.identifier, extension.identifier));
if (extension.server) {
const state = (extension.server === this.extensionManagementServerService.localExtensionManagementServer ? this.localExtensions! : this.remoteExtensions!).getExtensionState(extension);
const state = (extension.server === this.extensionManagementServerService.localExtensionManagementServer
? this.localExtensions! : extension.server === this.extensionManagementServerService.remoteExtensionManagementServer ? this.remoteExtensions! : this.webExtensions!).getExtensionState(extension);
return state === ExtensionState.Uninstalled && isInstalling ? ExtensionState.Installing : state;
} else if (isInstalling) {
return ExtensionState.Installing;
@@ -727,6 +749,12 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return state;
}
}
if (this.webExtensions) {
const state = this.webExtensions.getExtensionState(extension);
if (state !== ExtensionState.Uninstalled) {
return state;
}
}
if (this.localExtensions) {
return this.localExtensions.getExtensionState(extension);
}
@@ -805,7 +833,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
return false;
}
if (this.extensionManagementServerService.localExtensionManagementServer || this.extensionManagementServerService.remoteExtensionManagementServer) {
if (this.extensionManagementServerService.localExtensionManagementServer
|| this.extensionManagementServerService.remoteExtensionManagementServer
|| this.extensionManagementServerService.webExtensionManagementServer) {
return true;
}
@@ -920,9 +950,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
}
isExtensionIgnoredToSync(extension: IExtension): boolean {
const localExtensions = (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer
? this.local.filter(i => i.server === this.extensionManagementServerService.localExtensionManagementServer)
: this.local)
const localExtensions = (!isWeb && this.localExtensions ? this.localExtensions.local : this.local)
.filter(l => !!l.local)
.map(l => l.local!);
@@ -1112,7 +1140,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
private _activityCallBack: (() => void) | null = null;
private updateActivity(): void {
if ((this.localExtensions && this.localExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling))
|| (this.remoteExtensions && this.remoteExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling))) {
|| (this.remoteExtensions && this.remoteExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling))
|| (this.webExtensions && this.webExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling))) {
if (!this._activityCallBack) {
this.progressService.withProgress({ location: ProgressLocation.Extensions }, () => new Promise(c => this._activityCallBack = c));
}

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { flatten } from 'vs/base/common/arrays';
import { EXTENSION_CATEGORIES } from 'vs/platform/extensions/common/extensions';
export class Query {
@@ -15,7 +16,7 @@ export class Query {
const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext', 'id'] as const;
const subcommands = {
'sort': ['installs', 'rating', 'name'],
'category': ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'],
'category': EXTENSION_CATEGORIES.map(c => `"${c.toLowerCase()}"`),
'tag': [''],
'ext': [''],
'id': ['']

View File

@@ -60,7 +60,7 @@ Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactor
// Global actions
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchActionExtensions.WorkbenchActions);
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ShowRuntimeExtensionsAction), 'Show Running Extensions', localize('developer', "Developer"));
actionRegistry.registerWorkbenchAction(SyncActionDescriptor.from(ShowRuntimeExtensionsAction), 'Show Running Extensions', localize({ key: 'developer', comment: ['A developer on Code itself or someone diagnosing issues in Code'] }, "Developer"));
class ExtensionsContributions implements IWorkbenchContribution {

View File

@@ -34,7 +34,7 @@ import { URI } from 'vs/base/common/uri';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
import { ExtensionIdentifier, IExtensionContributions, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtensionIdentifier, IExtensionContributions, ExtensionType, IExtensionDescription, IExtension } from 'vs/platform/extensions/common/extensions';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ILabelService, IFormatterChangeEvent } from 'vs/platform/label/common/label';
@@ -99,7 +99,7 @@ async function setupTest() {
instantiationService.stub(IRemoteAgentService, RemoteAgentService);
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', id: 'vscode-local' };
constructor() {
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IConfigurationService), instantiationService.get(IProductService), instantiationService.get(ILogService), instantiationService.get(ILabelService));
}
@@ -1122,7 +1122,7 @@ suite('ReloadAction', () => {
test('Test ReloadAction when extension is newly installed', async () => {
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
const runningExtensions = [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }];
const runningExtensions = [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))];
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
getExtensions: () => Promise.resolve(runningExtensions),
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
@@ -1145,7 +1145,7 @@ suite('ReloadAction', () => {
test('Test ReloadAction when extension is newly installed and reload is not required', async () => {
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
const runningExtensions = [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }];
const runningExtensions = [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))];
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
getExtensions: () => Promise.resolve(runningExtensions),
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
@@ -1166,7 +1166,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is installed and uninstalled', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const gallery = aGalleryExtension('a');
@@ -1184,7 +1184,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is uninstalled', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), extensionLocation: URI.file('pub.a'), version: '1.0.0' }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('a', { version: '1.0.0' }))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const local = aLocalExtension('a');
@@ -1218,7 +1218,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is uninstalled and installed', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), version: '1.0.0', extensionLocation: URI.file('pub.a') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('a', { version: '1.0.0' }))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const local = aLocalExtension('a');
@@ -1238,7 +1238,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is updated while running', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), version: '1.0.1', extensionLocation: URI.file('pub.a') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('a', { version: '1.0.1' }))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const local = aLocalExtension('a', { version: '1.0.1' });
@@ -1260,7 +1260,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is updated when not running', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))]);
const local = aLocalExtension('a', { version: '1.0.1' });
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
@@ -1278,7 +1278,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is disabled when running', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), extensionLocation: URI.file('pub.a') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('a'))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const local = aLocalExtension('a');
@@ -1294,7 +1294,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension enablement is toggled when running', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), version: '1.0.0', extensionLocation: URI.file('pub.a') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('a', { version: '1.0.0' }))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const local = aLocalExtension('a');
@@ -1308,7 +1308,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is enabled when not running', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))]);
const local = aLocalExtension('a');
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
@@ -1324,7 +1324,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension enablement is toggled when not running', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))]);
const local = aLocalExtension('a');
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
@@ -1339,7 +1339,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when extension is updated when not running and enabled', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))]);
const local = aLocalExtension('a', { version: '1.0.1' });
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
@@ -1359,7 +1359,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when a localization extension is newly installed', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('b'))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const gallery = aGalleryExtension('a');
@@ -1375,7 +1375,7 @@ suite('ReloadAction', () => {
});
test('Test ReloadAction when a localization extension is updated while running', async () => {
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), version: '1.0.1', extensionLocation: URI.file('pub.a') }]);
instantiationService.stubPromise(IExtensionService, 'getExtensions', [ExtensionsActions.toExtensionDescription(aLocalExtension('a', { version: '1.0.1' }))]);
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
instantiationService.createInstance(ExtensionContainers, [testObject]);
const local = aLocalExtension('a', { version: '1.0.1', contributes: <IExtensionContributions>{ localizations: [{ languageId: 'de', translations: [] }] } });
@@ -2518,7 +2518,7 @@ function aPage<T>(...objects: T[]): IPager<T> {
function aSingleRemoteExtensionManagementServerService(instantiationService: TestInstantiationService, remoteExtensionManagementService?: IExtensionManagementService): IExtensionManagementServerService {
const remoteExtensionManagementServer: IExtensionManagementServer = {
authority: 'vscode-remote',
id: 'vscode-remote',
label: 'remote',
extensionManagementService: remoteExtensionManagementService || createExtensionManagementService()
};
@@ -2526,8 +2526,9 @@ function aSingleRemoteExtensionManagementServerService(instantiationService: Tes
_serviceBrand: undefined,
localExtensionManagementServer: null,
remoteExtensionManagementServer,
getExtensionManagementServer: (location: URI) => {
if (location.scheme === REMOTE_HOST_SCHEME) {
webExtensionManagementServer: null,
getExtensionManagementServer: (extension: IExtension) => {
if (extension.location.scheme === REMOTE_HOST_SCHEME) {
return remoteExtensionManagementServer;
}
return null;
@@ -2537,12 +2538,12 @@ function aSingleRemoteExtensionManagementServerService(instantiationService: Tes
function aMultiExtensionManagementServerService(instantiationService: TestInstantiationService, localExtensionManagementService?: IExtensionManagementService, remoteExtensionManagementService?: IExtensionManagementService): IExtensionManagementServerService {
const localExtensionManagementServer: IExtensionManagementServer = {
authority: 'vscode-local',
id: 'vscode-local',
label: 'local',
extensionManagementService: localExtensionManagementService || createExtensionManagementService()
};
const remoteExtensionManagementServer: IExtensionManagementServer = {
authority: 'vscode-remote',
id: 'vscode-remote',
label: 'remote',
extensionManagementService: remoteExtensionManagementService || createExtensionManagementService()
};
@@ -2550,14 +2551,15 @@ function aMultiExtensionManagementServerService(instantiationService: TestInstan
_serviceBrand: undefined,
localExtensionManagementServer,
remoteExtensionManagementServer,
getExtensionManagementServer: (location: URI) => {
if (location.scheme === Schemas.file) {
webExtensionManagementServer: null,
getExtensionManagementServer: (extension: IExtension) => {
if (extension.location.scheme === Schemas.file) {
return localExtensionManagementServer;
}
if (location.scheme === REMOTE_HOST_SCHEME) {
if (extension.location.scheme === REMOTE_HOST_SCHEME) {
return remoteExtensionManagementServer;
}
return null;
throw new Error('');
}
};
}

View File

@@ -99,7 +99,7 @@ suite('ExtensionsListView Tests', () => {
instantiationService.stub(IMenuService, new TestMenuService());
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', id: 'vscode-local' };
constructor() {
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IConfigurationService), instantiationService.get(IProductService), instantiationService.get(ILogService), instantiationService.get(ILabelService));
}