mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-30 00:30:29 -04:00
Merge from vscode 817eb6b0c720a4ecbc13c020afbbebfed667aa09 (#7356)
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
|
||||
import 'vs/css!./media/extensionEditor';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as marked from 'vs/base/common/marked/marked';
|
||||
import { createCancelablePromise } from 'vs/base/common/async';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { OS } from 'vs/base/common/platform';
|
||||
@@ -56,6 +55,11 @@ import { renderDashboardContributions } from 'sql/workbench/parts/extensions/bro
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { platform } from 'vs/base/common/process';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { renderMarkdownDocument } from 'vs/workbench/common/markdownDocumentRenderer';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { TokenizationRegistry } from 'vs/editor/common/modes';
|
||||
import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/tokenization';
|
||||
|
||||
function removeEmbeddedSVGs(documentContent: string): string {
|
||||
const newDocument = new DOMParser().parseFromString(documentContent, 'text/html');
|
||||
@@ -187,7 +191,8 @@ export class ExtensionEditor extends BaseEditor {
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
|
||||
@IWebviewService private readonly webviewService: IWebviewService
|
||||
@IWebviewService private readonly webviewService: IWebviewService,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
) {
|
||||
super(ExtensionEditor.ID, telemetryService, themeService, storageService);
|
||||
this.extensionReadme = null;
|
||||
@@ -580,44 +585,68 @@ export class ExtensionEditor extends BaseEditor {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
private openMarkdown(cacheResult: CacheResult<string>, noContentCopy: string, template: IExtensionEditorTemplate): Promise<IActiveElement> {
|
||||
return this.loadContents(() => cacheResult, template)
|
||||
.then(marked.parse)
|
||||
.then(content => this.renderBody(content))
|
||||
.then(removeEmbeddedSVGs)
|
||||
.then(body => {
|
||||
const webviewElement = this.webviewService.createWebview('extensionEditor',
|
||||
{
|
||||
enableFindWidget: true,
|
||||
},
|
||||
{});
|
||||
webviewElement.mountTo(template.content);
|
||||
this.contentDisposables.add(webviewElement.onDidFocus(() => this.fireOnDidFocus()));
|
||||
const removeLayoutParticipant = arrays.insert(this.layoutParticipants, webviewElement);
|
||||
this.contentDisposables.add(toDisposable(removeLayoutParticipant));
|
||||
webviewElement.html = body;
|
||||
private async openMarkdown(cacheResult: CacheResult<string>, noContentCopy: string, template: IExtensionEditorTemplate): Promise<IActiveElement> {
|
||||
try {
|
||||
const body = await this.renderMarkdown(cacheResult, template);
|
||||
|
||||
this.contentDisposables.add(webviewElement.onDidClickLink(link => {
|
||||
if (!link) {
|
||||
return;
|
||||
}
|
||||
// Whitelist supported schemes for links
|
||||
if (['http', 'https', 'mailto'].indexOf(link.scheme) >= 0 || (link.scheme === 'command' && link.path === ShowCurrentReleaseNotesActionId)) {
|
||||
this.openerService.open(link);
|
||||
}
|
||||
}, null, this.contentDisposables));
|
||||
this.contentDisposables.add(webviewElement);
|
||||
return webviewElement;
|
||||
})
|
||||
.then(undefined, () => {
|
||||
const p = append(template.content, $('p.nocontent'));
|
||||
p.textContent = noContentCopy;
|
||||
return p;
|
||||
const webviewElement = this.contentDisposables.add(this.webviewService.createWebviewEditorOverlay('extensionEditor', {
|
||||
enableFindWidget: true,
|
||||
}, {}));
|
||||
|
||||
webviewElement.claim(this);
|
||||
webviewElement.layoutWebviewOverElement(template.content);
|
||||
webviewElement.html = body;
|
||||
|
||||
this.contentDisposables.add(webviewElement.onDidFocus(() => this.fireOnDidFocus()));
|
||||
const removeLayoutParticipant = arrays.insert(this.layoutParticipants, {
|
||||
layout: () => {
|
||||
webviewElement.layout();
|
||||
webviewElement.layoutWebviewOverElement(template.content);
|
||||
}
|
||||
});
|
||||
this.contentDisposables.add(toDisposable(removeLayoutParticipant));
|
||||
|
||||
let isDisposed = false;
|
||||
this.contentDisposables.add(toDisposable(() => { isDisposed = true; }));
|
||||
|
||||
this.contentDisposables.add(this.themeService.onThemeChange(async () => {
|
||||
// Render again since syntax highlighting of code blocks may have changed
|
||||
const body = await this.renderMarkdown(cacheResult, template);
|
||||
if (!isDisposed) { // Make sure we weren't disposed of in the meantime
|
||||
webviewElement.html = body;
|
||||
}
|
||||
}));
|
||||
|
||||
this.contentDisposables.add(webviewElement.onDidClickLink(link => {
|
||||
if (!link) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Whitelist supported schemes for links
|
||||
if ([Schemas.http, Schemas.https, Schemas.mailto].indexOf(link.scheme) >= 0 || (link.scheme === 'command' && link.path === ShowCurrentReleaseNotesActionId)) {
|
||||
this.openerService.open(link);
|
||||
}
|
||||
}, null, this.contentDisposables));
|
||||
|
||||
return webviewElement;
|
||||
} catch (e) {
|
||||
const p = append(template.content, $('p.nocontent'));
|
||||
p.textContent = noContentCopy;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
private async renderMarkdown(cacheResult: CacheResult<string>, template: IExtensionEditorTemplate) {
|
||||
const contents = await this.loadContents(() => cacheResult, template);
|
||||
const content = await renderMarkdownDocument(contents, this.extensionService, this.modeService);
|
||||
const documentContent = await this.renderBody(content);
|
||||
return removeEmbeddedSVGs(documentContent);
|
||||
}
|
||||
|
||||
private async renderBody(body: string): Promise<string> {
|
||||
const nonce = generateUuid();
|
||||
const colorMap = TokenizationRegistry.getColorMap();
|
||||
const css = colorMap ? generateTokensCSSForColorMap(colorMap) : '';
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -695,14 +724,9 @@ export class ExtensionEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
|
||||
font-size: 14px;
|
||||
line-height: 19px;
|
||||
}
|
||||
|
||||
.mac code {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
font-family: var(--vscode-editor-font-family);
|
||||
font-weight: var(--vscode-editor-font-weight);
|
||||
font-size: var(--vscode-editor-font-size);
|
||||
}
|
||||
|
||||
code > div {
|
||||
@@ -711,6 +735,10 @@ export class ExtensionEditor extends BaseEditor {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.monaco-tokenized-source {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#scroll-to-top {
|
||||
position: fixed;
|
||||
width: 40px;
|
||||
@@ -795,6 +823,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
border-color: rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
|
||||
${css}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -26,7 +26,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
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 { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
@@ -1178,7 +1178,7 @@ export class ReloadAction extends ExtensionAction {
|
||||
|
||||
constructor(
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
|
||||
@@ -1230,7 +1230,7 @@ export class ReloadAction extends ExtensionAction {
|
||||
if (this.extension.local) {
|
||||
const isEnabled = this.extensionEnablementService.isEnabled(this.extension.local);
|
||||
|
||||
// Extension is runningÎ
|
||||
// Extension is running
|
||||
if (runningExtension) {
|
||||
if (isEnabled) {
|
||||
if (!this.extensionService.canAddExtension(toExtensionDescription(this.extension.local))) {
|
||||
@@ -1241,11 +1241,6 @@ export class ReloadAction extends ExtensionAction {
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
this.tooltip = localize('postUpdateTooltip', "Please reload Azure Data Studio to enable the updated extension.");
|
||||
}
|
||||
} else {
|
||||
this.enabled = true;
|
||||
this.label = localize('reloadRequired', "Reload Required");
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1285,7 +1280,7 @@ export class ReloadAction extends ExtensionAction {
|
||||
}
|
||||
|
||||
run(): Promise<any> {
|
||||
return Promise.resolve(this.windowService.reloadWindow());
|
||||
return Promise.resolve(this.hostService.reload());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1634,6 +1629,29 @@ export class ShowRecommendedExtensionsAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class ShowSyncedExtensionsAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.extensions.action.listSyncedExtensions';
|
||||
static LABEL = localize('showSyncedExtensions', "Show My Accoount Extensions");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IViewletService private readonly viewletService: IViewletService
|
||||
) {
|
||||
super(id, label, undefined, true);
|
||||
}
|
||||
|
||||
run(): Promise<void> {
|
||||
return this.viewletService.openViewlet(VIEWLET_ID, true)
|
||||
.then(viewlet => viewlet as IExtensionsViewlet)
|
||||
.then(viewlet => {
|
||||
viewlet.search('@myaccount ');
|
||||
viewlet.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class InstallWorkspaceRecommendedExtensionsAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.extensions.action.installWorkspaceRecommendedExtensions';
|
||||
@@ -2622,11 +2640,10 @@ export class SystemDisabledWarningAction extends ExtensionAction {
|
||||
|
||||
constructor(
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
|
||||
) {
|
||||
super('extensions.install', '', `${SystemDisabledWarningAction.CLASS} hide`, false);
|
||||
this._register(this.labelService.onDidChangeFormatters(() => this.update(), this));
|
||||
@@ -2662,32 +2679,24 @@ export class SystemDisabledWarningAction extends ExtensionAction {
|
||||
return;
|
||||
}
|
||||
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 localExtension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier))[0];
|
||||
const localExtensionServer = localExtension ? localExtension.server : null;
|
||||
if (this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && !isUIExtension(this.extension.local.manifest, this.productService, this.configurationService)) {
|
||||
if (runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
if (!runningExtension && this.extension.enablementState === EnablementState.DisabledByExtensionKind) {
|
||||
this.class = `${SystemDisabledWarningAction.WARNING_CLASS}`;
|
||||
const server = this.extensionManagementServerService.localExtensionManagementServer === this.extension.server ? this.extensionManagementServerService.remoteExtensionManagementServer : this.extensionManagementServerService.localExtensionManagementServer;
|
||||
this.tooltip = localize('Install in other server to enable', "Install the extension on '{0}' to enable.", server.label);
|
||||
return;
|
||||
}
|
||||
if (this.extensionEnablementService.isEnabled(this.extension.local)) {
|
||||
const runningExtensionServer = runningExtension ? this.extensionManagementServerService.getExtensionManagementServer(runningExtension.extensionLocation) : null;
|
||||
if (this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;
|
||||
this.tooltip = localize('disabled locally', "Extension is enabled on '{0}' and disabled locally.", this.extensionManagementServerService.remoteExtensionManagementServer.label);
|
||||
return;
|
||||
}
|
||||
if (localExtensionServer !== this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
this.class = `${SystemDisabledWarningAction.WARNING_CLASS}`;
|
||||
this.tooltip = localize('Install in remote server', "Install the extension on '{0}' to enable.", this.extensionManagementServerService.remoteExtensionManagementServer.label);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && isUIExtension(this.extension.local.manifest, this.productService, this.configurationService)) {
|
||||
if (runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;
|
||||
this.tooltip = localize('disabled remotely', "Extension is enabled locally and disabled on '{0}'.", this.extensionManagementServerService.remoteExtensionManagementServer.label);
|
||||
return;
|
||||
}
|
||||
if (localExtensionServer !== this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
this.class = `${SystemDisabledWarningAction.WARNING_CLASS}`;
|
||||
this.tooltip = localize('Install in local server', "Install the extension locally to enable.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2810,10 +2819,9 @@ export class InstallVSIXAction extends Action {
|
||||
label = InstallVSIXAction.LABEL,
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@IFileDialogService private readonly fileDialogService: IFileDialogService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
// {{SQL CARBON EDIT}}
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IStorageService private storageService: IStorageService
|
||||
@@ -2825,17 +2833,17 @@ export class InstallVSIXAction extends Action {
|
||||
// {{SQL CARBON EDIT}} - Replace run body
|
||||
let extensionPolicy = this.configurationService.getValue<string>(ExtensionsPolicyKey);
|
||||
if (extensionPolicy === ExtensionsPolicy.allowAll) {
|
||||
return Promise.resolve(this.windowService.showOpenDialog({
|
||||
return Promise.resolve(this.fileDialogService.showOpenDialog({
|
||||
title: localize('installFromVSIX', "Install from VSIX"),
|
||||
filters: [{ name: 'VSIX Extensions', extensions: ['vsix'] }],
|
||||
properties: ['openFile'],
|
||||
buttonLabel: mnemonicButtonLabel(localize({ key: 'installButton', comment: ['&& denotes a mnemonic'] }, "&&Install"))
|
||||
canSelectFiles: true,
|
||||
openLabel: mnemonicButtonLabel(localize({ key: 'installButton', comment: ['&& denotes a mnemonic'] }, "&&Install"))
|
||||
}).then(result => {
|
||||
if (!result) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.all(result.map(vsix => {
|
||||
if (!this.storageService.getBoolean(vsix, StorageScope.GLOBAL)) {
|
||||
if (!this.storageService.getBoolean(vsix.fsPath, StorageScope.GLOBAL)) {
|
||||
this.notificationService.prompt(
|
||||
Severity.Warning,
|
||||
localize('thirdPartyExtension.vsix', 'This is a third party extension and might involve security risks. Are you sure you want to install this extension?'),
|
||||
@@ -2843,13 +2851,13 @@ export class InstallVSIXAction extends Action {
|
||||
{
|
||||
label: localize('thirdPartExt.yes', 'Yes'),
|
||||
run: () => {
|
||||
this.extensionsWorkbenchService.install(URI.file(vsix)).then(extension => {
|
||||
this.extensionsWorkbenchService.install(vsix).then(extension => {
|
||||
const requireReload = !(extension.local && this.extensionService.canAddExtension(toExtensionDescription(extension.local)));
|
||||
const message = requireReload ? localize('InstallVSIXAction.successReload', "Please reload Azure Data Studio to complete installing the extension {0}.", extension.identifier.id)
|
||||
: localize('InstallVSIXAction.success', "Completed installing the extension {0}.", extension.identifier.id);
|
||||
const actions = requireReload ? [{
|
||||
label: localize('InstallVSIXAction.reloadNow', "Reload Now"),
|
||||
run: () => this.windowService.reloadWindow()
|
||||
run: () => this.hostService.reload()
|
||||
}] : [];
|
||||
this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
@@ -2868,7 +2876,7 @@ export class InstallVSIXAction extends Action {
|
||||
label: localize('thirdPartyExt.dontShowAgain', 'Don\'t Show Again'),
|
||||
isSecondary: true,
|
||||
run: () => {
|
||||
this.storageService.store(vsix, true, StorageScope.GLOBAL);
|
||||
this.storageService.store(vsix.fsPath, true, StorageScope.GLOBAL);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
@@ -2876,13 +2884,13 @@ export class InstallVSIXAction extends Action {
|
||||
{ sticky: true }
|
||||
);
|
||||
} else {
|
||||
this.extensionsWorkbenchService.install(URI.file(vsix)).then(extension => {
|
||||
this.extensionsWorkbenchService.install(vsix).then(extension => {
|
||||
const requireReload = !(extension.local && this.extensionService.canAddExtension(toExtensionDescription(extension.local)));
|
||||
const message = requireReload ? localize('InstallVSIXAction.successReload', "Please reload Azure Data Studio to complete installing the extension {0}.", extension.identifier.id)
|
||||
: localize('InstallVSIXAction.success', "Completed installing the extension {0}.", extension.identifier.id);
|
||||
const actions = requireReload ? [{
|
||||
label: localize('InstallVSIXAction.reloadNow', "Reload Now"),
|
||||
run: () => this.windowService.reloadWindow()
|
||||
run: () => this.hostService.reload()
|
||||
}] : [];
|
||||
this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
@@ -2912,7 +2920,7 @@ export class ReinstallAction extends Action {
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService
|
||||
) {
|
||||
@@ -2956,7 +2964,7 @@ export class ReinstallAction extends Action {
|
||||
: localize('ReinstallAction.success', "Reinstalling the extension {0} is completed.", extension.identifier.id);
|
||||
const actions = requireReload ? [{
|
||||
label: localize('InstallVSIXAction.reloadNow', "Reload Now"),
|
||||
run: () => this.windowService.reloadWindow()
|
||||
run: () => this.hostService.reload()
|
||||
}] : [];
|
||||
this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
@@ -2980,7 +2988,7 @@ export class InstallSpecificVersionOfExtensionAction extends Action {
|
||||
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
|
||||
@@ -3042,7 +3050,7 @@ export class InstallSpecificVersionOfExtensionAction extends Action {
|
||||
: localize('InstallAnotherVersionExtensionAction.success', "Installing the extension {0} is completed.", extension.identifier.id);
|
||||
const actions = requireReload ? [{
|
||||
label: localize('InstallAnotherVersionExtensionAction.reloadNow', "Reload Now"),
|
||||
run: () => this.windowService.reloadWindow()
|
||||
run: () => this.hostService.reload()
|
||||
}] : [];
|
||||
this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
@@ -3069,7 +3077,7 @@ export class InstallLocalExtensionsInRemoteAction extends Action {
|
||||
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@IProgressService private readonly progressService: IProgressService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
@@ -3182,7 +3190,7 @@ export class InstallLocalExtensionsInRemoteAction extends Action {
|
||||
message: localize('finished installing', "Successfully installed extensions in {0}. Please reload the window to enable them.", this.extensionManagementServerService.remoteExtensionManagementServer!.label),
|
||||
actions: {
|
||||
primary: [new Action('realod', localize('reload', "Reload Window"), '', true,
|
||||
() => this.windowService.reloadWindow())]
|
||||
() => this.hostService.reload())]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { values } from 'vs/base/common/map';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
@@ -23,7 +23,7 @@ export class ExtensionDependencyChecker extends Disposable implements IWorkbench
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWindowService private readonly windowService: IWindowService
|
||||
@IHostService private readonly hostService: IHostService
|
||||
) {
|
||||
super();
|
||||
CommandsRegistry.registerCommand('workbench.extensions.installMissingDepenencies', () => this.installMissingDependencies());
|
||||
@@ -69,7 +69,7 @@ export class ExtensionDependencyChecker extends Disposable implements IWorkbench
|
||||
message: localize('finished installing missing deps', "Finished installing missing dependencies. Please reload the window now."),
|
||||
actions: {
|
||||
primary: [new Action('realod', localize('reload', "Reload Window"), '', true,
|
||||
() => this.windowService.reloadWindow())]
|
||||
() => this.hostService.reload())]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, AutoUpdate
|
||||
import {
|
||||
ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowDisabledExtensionsAction,
|
||||
ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction,
|
||||
EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction
|
||||
EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, ShowSyncedExtensionsAction
|
||||
} from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput';
|
||||
import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInExtensionsView, BuiltInThemesExtensionsView, BuiltInBasicsExtensionsView, ServerExtensionsView, DefaultRecommendedExtensionsView } from 'vs/workbench/contrib/extensions/browser/extensionsViews';
|
||||
import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInExtensionsView, BuiltInThemesExtensionsView, BuiltInBasicsExtensionsView, ServerExtensionsView, DefaultRecommendedExtensionsView, SyncedExtensionsView } from 'vs/workbench/contrib/extensions/browser/extensionsViews';
|
||||
import { OpenGlobalSettingsAction } from 'vs/workbench/contrib/preferences/browser/preferencesActions';
|
||||
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
@@ -43,7 +43,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IAddedViewDescriptorRef } from 'vs/workbench/browser/parts/views/views';
|
||||
import { ViewletPanel } from 'vs/workbench/browser/parts/views/panelViewlet';
|
||||
@@ -58,6 +58,7 @@ import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsView
|
||||
import { RemoteNameContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { MementoObject } from 'vs/workbench/common/memento';
|
||||
import { SyncStatus, CONTEXT_SYNC_STATE } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
|
||||
const NonEmptyWorkspaceContext = new RawContextKey<boolean>('nonEmptyWorkspace', false);
|
||||
const DefaultViewsContext = new RawContextKey<boolean>('defaultExtensionViews', true);
|
||||
@@ -70,6 +71,7 @@ const HasInstalledExtensionsContext = new RawContextKey<boolean>('hasInstalledEx
|
||||
const SearchBuiltInExtensionsContext = new RawContextKey<boolean>('searchBuiltInExtensions', false);
|
||||
const RecommendedExtensionsContext = new RawContextKey<boolean>('recommendedExtensions', false);
|
||||
const DefaultRecommendedExtensionsContext = new RawContextKey<boolean>('defaultRecommendedExtensions', false);
|
||||
const SyncedExtensionsContext = new RawContextKey<boolean>('syncedExtensions', false);
|
||||
const viewIdNameMappings: { [id: string]: string } = {
|
||||
'extensions.listView': localize('marketPlace', "Marketplace"),
|
||||
'extensions.enabledExtensionList': localize('enabledExtensions', "Enabled"),
|
||||
@@ -84,6 +86,7 @@ const viewIdNameMappings: { [id: string]: string } = {
|
||||
'extensions.builtInExtensionsList': localize('builtInExtensions', "Features"),
|
||||
'extensions.builtInThemesExtensionsList': localize('builtInThemesExtensions', "Themes"),
|
||||
'extensions.builtInBasicsExtensionsList': localize('builtInBasicsExtensions', "Programming Languages"),
|
||||
'extensions.syncedExtensionsList': localize('syncedExtensions', "My Account"),
|
||||
};
|
||||
|
||||
export class ExtensionsViewletViewsContribution implements IWorkbenchContribution {
|
||||
@@ -110,6 +113,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
viewDescriptors.push(this.createDefaultRecommendedExtensionsListViewDescriptor());
|
||||
viewDescriptors.push(this.createOtherRecommendedExtensionsListViewDescriptor());
|
||||
viewDescriptors.push(this.createWorkspaceRecommendedExtensionsListViewDescriptor());
|
||||
viewDescriptors.push(this.createSyncedExtensionsViewDescriptor());
|
||||
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
viewDescriptors.push(...this.createExtensionsViewDescriptorsForServer(this.extensionManagementServerService.localExtensionManagementServer));
|
||||
@@ -314,6 +318,17 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
weight: 100
|
||||
};
|
||||
}
|
||||
|
||||
private createSyncedExtensionsViewDescriptor(): IViewDescriptor {
|
||||
const id = 'extensions.syncedExtensionsList';
|
||||
return {
|
||||
id,
|
||||
name: viewIdNameMappings[id],
|
||||
ctorDescriptor: { ctor: SyncedExtensionsView },
|
||||
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), ContextKeyExpr.has('config.userConfiguration.enableSync'), ContextKeyExpr.has('syncedExtensions')),
|
||||
weight: 100
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensionsViewlet {
|
||||
@@ -330,6 +345,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
private hasInstalledExtensionsContextKey: IContextKey<boolean>;
|
||||
private searchBuiltInExtensionsContextKey: IContextKey<boolean>;
|
||||
private recommendedExtensionsContextKey: IContextKey<boolean>;
|
||||
private syncedExtensionsContextKey: IContextKey<boolean>;
|
||||
private defaultRecommendedExtensionsContextKey: IContextKey<boolean>;
|
||||
|
||||
private searchDelayer: Delayer<void>;
|
||||
@@ -371,6 +387,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
this.recommendedExtensionsContextKey = RecommendedExtensionsContext.bindTo(contextKeyService);
|
||||
this.defaultRecommendedExtensionsContextKey = DefaultRecommendedExtensionsContext.bindTo(contextKeyService);
|
||||
this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue<boolean>(ShowRecommendationsOnlyOnDemandKey));
|
||||
this.syncedExtensionsContextKey = SyncedExtensionsContext.bindTo(contextKeyService);
|
||||
this._register(this.viewletService.onDidViewletOpen(this.onViewletOpen, this));
|
||||
this.searchViewletState = this.getMemento(StorageScope.WORKSPACE);
|
||||
|
||||
@@ -469,8 +486,8 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
this.instantiationService.createInstance(ShowDisabledExtensionsAction, ShowDisabledExtensionsAction.ID, ShowDisabledExtensionsAction.LABEL),
|
||||
this.instantiationService.createInstance(ShowBuiltInExtensionsAction, ShowBuiltInExtensionsAction.ID, ShowBuiltInExtensionsAction.LABEL),
|
||||
this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, ShowRecommendedExtensionsAction.LABEL),
|
||||
// {{SQL CARBON EDIT}}
|
||||
// this.instantiationService.createInstance(ShowPopularExtensionsAction, ShowPopularExtensionsAction.ID, ShowPopularExtensionsAction.LABEL),
|
||||
// this.instantiationService.createInstance(ShowPopularExtensionsAction, ShowPopularExtensionsAction.ID, ShowPopularExtensionsAction.LABEL), // {{SQL CARBON EDIT}}
|
||||
this.instantiationService.createInstance(ShowSyncedExtensionsAction, ShowSyncedExtensionsAction.ID, ShowSyncedExtensionsAction.LABEL),
|
||||
new Separator(),
|
||||
// {{SQL CARBON EDIT}}
|
||||
//this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.install', localize('sort by installs', "Sort By: Install Count"), this.onSearchChange, 'installs'),
|
||||
@@ -519,6 +536,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
|
||||
private doSearch(): Promise<void> {
|
||||
const value = this.normalizedQuery();
|
||||
const isSyncedExtensionsQuery = ExtensionsListView.isSyncedExtensionsQuery(value);
|
||||
const isRecommendedExtensionsQuery = ExtensionsListView.isRecommendedExtensionsQuery(value);
|
||||
this.searchInstalledExtensionsContextKey.set(ExtensionsListView.isInstalledExtensionsQuery(value));
|
||||
this.searchOutdatedExtensionsContextKey.set(ExtensionsListView.isOutdatedExtensionsQuery(value));
|
||||
@@ -526,7 +544,8 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
this.searchDisabledExtensionsContextKey.set(ExtensionsListView.isDisabledExtensionsQuery(value));
|
||||
this.searchBuiltInExtensionsContextKey.set(ExtensionsListView.isBuiltInExtensionsQuery(value));
|
||||
this.recommendedExtensionsContextKey.set(isRecommendedExtensionsQuery);
|
||||
this.searchMarketplaceExtensionsContextKey.set(!!value && !ExtensionsListView.isLocalExtensionsQuery(value) && !isRecommendedExtensionsQuery);
|
||||
this.syncedExtensionsContextKey.set(isSyncedExtensionsQuery);
|
||||
this.searchMarketplaceExtensionsContextKey.set(!!value && !ExtensionsListView.isLocalExtensionsQuery(value) && !isRecommendedExtensionsQuery && !isSyncedExtensionsQuery);
|
||||
this.nonEmptyWorkspaceContextKey.set(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY);
|
||||
this.defaultViewsContextKey.set(!value);
|
||||
|
||||
@@ -647,7 +666,7 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IExtensionManagementService private readonly extensionsManagementService: IExtensionManagementService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IHostService private readonly hostService: IHostService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService
|
||||
@@ -678,7 +697,7 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution {
|
||||
localize('malicious warning', "We have uninstalled '{0}' which was reported to be problematic.", e.identifier.id),
|
||||
[{
|
||||
label: localize('reloadNow', "Reload Now"),
|
||||
run: () => this.windowService.reloadWindow()
|
||||
run: () => this.hostService.reload()
|
||||
}],
|
||||
{ sticky: true }
|
||||
);
|
||||
|
||||
@@ -47,6 +47,7 @@ import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IUserDataSyncService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
|
||||
|
||||
class ExtensionsViewState extends Disposable implements IExtensionsViewState {
|
||||
@@ -104,6 +105,7 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IProductService protected readonly productService: IProductService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
|
||||
) {
|
||||
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title, showActionsAlways: true }, keybindingService, contextMenuService, configurationService, contextKeyService);
|
||||
this.server = options.server;
|
||||
@@ -456,8 +458,10 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
} else if (ExtensionsListView.isRecommendedExtensionsQuery(query.value)) {
|
||||
return this.getRecommendationsModel(query, options, token);
|
||||
// {{SQL CARBON EDIT}}
|
||||
} else if (ExtensionsListView.isAllMarketplaceExtensionsQuery(query.value)) {
|
||||
} else if (ExtensionsListView.isAllMarketplaceExtensionsQuery(query.value)) { // {{SQL CARBON EDIT}} add if
|
||||
return this.getAllMarketplaceModel(query, options, token);
|
||||
} else if (ExtensionsListView.isSyncedExtensionsQuery(query.value)) {
|
||||
return this.getSyncedExtensionsModel(query, options, token);
|
||||
}
|
||||
|
||||
if (/\bcurated:([^\s]+)\b/.test(query.value)) {
|
||||
@@ -765,6 +769,23 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
.then(result => this.getPagedModel(result));
|
||||
}
|
||||
|
||||
private async getSyncedExtensionsModel(query: Query, options: IQueryOptions, token: CancellationToken): Promise<IPagedModel<IExtension>> {
|
||||
const syncedExtensions = await this.userDataSyncService.getRemoteExtensions();
|
||||
if (!syncedExtensions.length) {
|
||||
return this.showEmptyModel();
|
||||
}
|
||||
const ids: string[] = [], names: string[] = [];
|
||||
for (const installed of syncedExtensions) {
|
||||
if (installed.identifier.uuid) {
|
||||
ids.push(installed.identifier.uuid);
|
||||
} else {
|
||||
names.push(installed.identifier.id);
|
||||
}
|
||||
}
|
||||
const pager = await this.extensionsWorkbenchService.queryGallery({ ids, names, pageSize: ids.length }, token);
|
||||
return this.getPagedModel(pager || []);
|
||||
}
|
||||
|
||||
// Sorts the firstPage of the pager in the same order as given array of extension ids
|
||||
private sortFirstPage(pager: IPager<IExtension>, ids: string[]) {
|
||||
ids = ids.map(x => x.toLowerCase());
|
||||
@@ -904,6 +925,10 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
return /@recommended:keymaps/i.test(query);
|
||||
}
|
||||
|
||||
static isSyncedExtensionsQuery(query: string): boolean {
|
||||
return /@myaccount/i.test(query);
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
super.focus();
|
||||
if (!this.list) {
|
||||
@@ -944,10 +969,11 @@ export class ServerExtensionsView extends ExtensionsListView {
|
||||
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IProductService productService: IProductService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IUserDataSyncService userDataSyncService: IUserDataSyncService
|
||||
) {
|
||||
options.server = server;
|
||||
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService);
|
||||
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService, userDataSyncService);
|
||||
this._register(onDidChangeTitle(title => this.updateTitle(title)));
|
||||
}
|
||||
|
||||
@@ -1003,6 +1029,14 @@ export class BuiltInBasicsExtensionsView extends ExtensionsListView {
|
||||
}
|
||||
}
|
||||
|
||||
export class SyncedExtensionsView extends ExtensionsListView {
|
||||
|
||||
async show(query: string): Promise<IPagedModel<IExtension>> {
|
||||
query = query || '@myaccount';
|
||||
return ExtensionsListView.isSyncedExtensionsQuery(query) ? super.show(query) : this.showEmptyModel();
|
||||
}
|
||||
}
|
||||
|
||||
export class DefaultRecommendedExtensionsView extends ExtensionsListView {
|
||||
// {{SQL CARBON EDIT}}
|
||||
private readonly recommendedExtensionsQuery = '@allmarketplace';
|
||||
|
||||
@@ -11,7 +11,7 @@ export const ExtensionsConfigurationSchemaId = 'vscode://schemas/extensions';
|
||||
export const ExtensionsConfigurationSchema: IJSONSchema = {
|
||||
id: ExtensionsConfigurationSchemaId,
|
||||
allowComments: true,
|
||||
allowsTrailingCommas: true,
|
||||
allowTrailingCommas: true,
|
||||
type: 'object',
|
||||
title: localize('app.extensions.json.title', "Extensions"),
|
||||
additionalProperties: false,
|
||||
@@ -39,7 +39,7 @@ export const ExtensionsConfigurationSchema: IJSONSchema = {
|
||||
|
||||
export const ExtensionsConfigurationInitialContent: string = [
|
||||
'{',
|
||||
'\t// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.',
|
||||
'\t// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.',
|
||||
'\t// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp',
|
||||
'',
|
||||
'\t// List of extensions which should be recommended for users of this workspace.',
|
||||
|
||||
@@ -12,7 +12,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { IExtensionHostProfileService, ProfileSessionState } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { randomPort } from 'vs/base/node/ports';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
@@ -46,7 +46,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
|
||||
@IExtensionService private readonly _extensionService: IExtensionService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IWindowsService private readonly _windowsService: IWindowsService,
|
||||
@IElectronService private readonly _electronService: IElectronService,
|
||||
@IDialogService private readonly _dialogService: IDialogService,
|
||||
@IStatusbarService private readonly _statusbarService: IStatusbarService,
|
||||
) {
|
||||
@@ -122,7 +122,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
|
||||
secondaryButton: nls.localize('cancel', "Cancel")
|
||||
}).then(res => {
|
||||
if (res.confirmed) {
|
||||
this._windowsService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] });
|
||||
this._electronService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { clipboard } from 'electron';
|
||||
import { EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { writeFile } from 'vs/base/node/pfs';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
@@ -307,7 +307,7 @@ export class RuntimeExtensionsEditor extends BaseEditor {
|
||||
|
||||
const activationTimes = element.status.activationTimes!;
|
||||
let syncTime = activationTimes.codeLoadingTime + activationTimes.activateCallTime;
|
||||
data.activationTime.textContent = activationTimes.startup ? `Startup Activation: ${syncTime}ms` : `Activation: ${syncTime}ms`;
|
||||
data.activationTime.textContent = activationTimes.activationReason.startup ? `Startup Activation: ${syncTime}ms` : `Activation: ${syncTime}ms`;
|
||||
|
||||
data.actionbar.clear();
|
||||
if (element.unresponsiveProfile) {
|
||||
@@ -318,43 +318,45 @@ export class RuntimeExtensionsEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
let title: string;
|
||||
if (activationTimes.activationEvent === '*') {
|
||||
title = nls.localize('starActivation', "Activated on start-up");
|
||||
} else if (/^workspaceContains:/.test(activationTimes.activationEvent)) {
|
||||
let fileNameOrGlob = activationTimes.activationEvent.substr('workspaceContains:'.length);
|
||||
const activationId = activationTimes.activationReason.extensionId.value;
|
||||
const activationEvent = activationTimes.activationReason.activationEvent;
|
||||
if (activationEvent === '*') {
|
||||
title = nls.localize('starActivation', "Activated by {0} on start-up", activationId);
|
||||
} else if (/^workspaceContains:/.test(activationEvent)) {
|
||||
let fileNameOrGlob = activationEvent.substr('workspaceContains:'.length);
|
||||
if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) {
|
||||
title = nls.localize({
|
||||
key: 'workspaceContainsGlobActivation',
|
||||
comment: [
|
||||
'{0} will be a glob pattern'
|
||||
]
|
||||
}, "Activated because a file matching {0} exists in your workspace", fileNameOrGlob);
|
||||
}, "Activated by {1} because a file matching {1} exists in your workspace", fileNameOrGlob, activationId);
|
||||
} else {
|
||||
title = nls.localize({
|
||||
key: 'workspaceContainsFileActivation',
|
||||
comment: [
|
||||
'{0} will be a file name'
|
||||
]
|
||||
}, "Activated because file {0} exists in your workspace", fileNameOrGlob);
|
||||
}, "Activated by {1} because file {0} exists in your workspace", fileNameOrGlob, activationId);
|
||||
}
|
||||
} else if (/^workspaceContainsTimeout:/.test(activationTimes.activationEvent)) {
|
||||
const glob = activationTimes.activationEvent.substr('workspaceContainsTimeout:'.length);
|
||||
} else if (/^workspaceContainsTimeout:/.test(activationEvent)) {
|
||||
const glob = activationEvent.substr('workspaceContainsTimeout:'.length);
|
||||
title = nls.localize({
|
||||
key: 'workspaceContainsTimeout',
|
||||
comment: [
|
||||
'{0} will be a glob pattern'
|
||||
]
|
||||
}, "Activated because searching for {0} took too long", glob);
|
||||
} else if (/^onLanguage:/.test(activationTimes.activationEvent)) {
|
||||
let language = activationTimes.activationEvent.substr('onLanguage:'.length);
|
||||
title = nls.localize('languageActivation', "Activated because you opened a {0} file", language);
|
||||
}, "Activated by {1} because searching for {0} took too long", glob, activationId);
|
||||
} else if (/^onLanguage:/.test(activationEvent)) {
|
||||
let language = activationEvent.substr('onLanguage:'.length);
|
||||
title = nls.localize('languageActivation', "Activated by {1} because you opened a {0} file", language, activationId);
|
||||
} else {
|
||||
title = nls.localize({
|
||||
key: 'workspaceGenericActivation',
|
||||
comment: [
|
||||
'The {0} placeholder will be an activation event, like e.g. \'language:typescript\', \'debug\', etc.'
|
||||
]
|
||||
}, "Activated on {0}", activationTimes.activationEvent);
|
||||
}, "Activated by {1} on {0}", activationEvent, activationId);
|
||||
}
|
||||
data.activationTime.title = title;
|
||||
|
||||
@@ -536,7 +538,7 @@ export class DebugExtensionHostAction extends Action {
|
||||
|
||||
constructor(
|
||||
@IDebugService private readonly _debugService: IDebugService,
|
||||
@IWindowsService private readonly _windowsService: IWindowsService,
|
||||
@IElectronService private readonly _electronService: IElectronService,
|
||||
@IDialogService private readonly _dialogService: IDialogService,
|
||||
@IExtensionService private readonly _extensionService: IExtensionService,
|
||||
) {
|
||||
@@ -555,7 +557,7 @@ export class DebugExtensionHostAction extends Action {
|
||||
secondaryButton: nls.localize('cancel', "Cancel")
|
||||
});
|
||||
if (res.confirmed) {
|
||||
this._windowsService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] });
|
||||
this._electronService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,7 +611,7 @@ export class SaveExtensionHostProfileAction extends Action {
|
||||
|
||||
constructor(
|
||||
id: string = SaveExtensionHostProfileAction.ID, label: string = SaveExtensionHostProfileAction.LABEL,
|
||||
@IWindowService private readonly _windowService: IWindowService,
|
||||
@IElectronService private readonly _electronService: IElectronService,
|
||||
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
|
||||
@IExtensionHostProfileService private readonly _extensionHostProfileService: IExtensionHostProfileService,
|
||||
) {
|
||||
@@ -624,7 +626,7 @@ export class SaveExtensionHostProfileAction extends Action {
|
||||
}
|
||||
|
||||
private async _asyncRun(): Promise<any> {
|
||||
let picked = await this._windowService.showSaveDialog({
|
||||
let picked = await this._electronService.showSaveDialog({
|
||||
title: 'Save Extension Host Profile',
|
||||
buttonLabel: 'Save',
|
||||
defaultPath: `CPU-${new Date().toISOString().replace(/[\-:]/g, '')}.cpuprofile`,
|
||||
@@ -634,13 +636,15 @@ export class SaveExtensionHostProfileAction extends Action {
|
||||
}]
|
||||
});
|
||||
|
||||
if (!picked) {
|
||||
if (!picked || !picked.filePath || picked.canceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const profileInfo = this._extensionHostProfileService.lastProfile;
|
||||
let dataToWrite: object = profileInfo ? profileInfo.data : {};
|
||||
|
||||
let savePath = picked.filePath;
|
||||
|
||||
if (this._environmentService.isBuilt) {
|
||||
const profiler = await import('v8-inspect-profiler');
|
||||
// when running from a not-development-build we remove
|
||||
@@ -651,9 +655,9 @@ export class SaveExtensionHostProfileAction extends Action {
|
||||
let tmp = profiler.rewriteAbsolutePaths({ profile: dataToWrite as any }, 'piiRemoved');
|
||||
dataToWrite = tmp.profile;
|
||||
|
||||
picked = picked + '.txt';
|
||||
savePath = savePath + '.txt';
|
||||
}
|
||||
|
||||
return writeFile(picked, JSON.stringify(profileInfo ? profileInfo.data : {}, null, '\t'));
|
||||
return writeFile(savePath, JSON.stringify(profileInfo ? profileInfo.data : {}, null, '\t'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1465,7 +1465,7 @@ suite('ExtensionsActions Test', () => {
|
||||
assert.equal(testObject.tooltip, 'Please reload Azure Data Studio to enable this extension.'); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
});
|
||||
|
||||
test('Test ReloadAction when ui extension is disabled on remote server and installed in local server', async () => {
|
||||
test('Test ReloadAction is disabled when remote ui extension is installed in local server', async () => {
|
||||
// multi server setup
|
||||
const gallery = aGalleryExtension('a');
|
||||
const localExtensionManagementService = createExtensionManagementService([]);
|
||||
@@ -1480,7 +1480,7 @@ suite('ExtensionsActions Test', () => {
|
||||
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve([]),
|
||||
getExtensions: () => Promise.resolve([ExtensionsActions.toExtensionDescription(remoteExtension)]),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
@@ -1497,8 +1497,69 @@ suite('ExtensionsActions Test', () => {
|
||||
const localExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file('pub.a') });
|
||||
onDidInstallEvent.fire({ identifier: localExtension.identifier, local: localExtension, operation: InstallOperation.Install });
|
||||
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal(testObject.tooltip, 'Please reload Azure Data Studio to enable this extension.'); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction for remote ui extension is disabled when it is installed and enabled in local server', async () => {
|
||||
// multi server setup
|
||||
const gallery = aGalleryExtension('a');
|
||||
const localExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file('pub.a') });
|
||||
const localExtensionManagementService = createExtensionManagementService([localExtension]);
|
||||
const onDidInstallEvent = new Emitter<DidInstallExtensionEvent>();
|
||||
localExtensionManagementService.onDidInstallExtension = onDidInstallEvent.event;
|
||||
const remoteExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file('pub.a').with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, localExtensionManagementService, createExtensionManagementService([remoteExtension]));
|
||||
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
|
||||
instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
|
||||
const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
|
||||
instantiationService.set(IExtensionsWorkbenchService, workbenchService);
|
||||
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve([ExtensionsActions.toExtensionDescription(localExtension)]),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.extension);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction for local ui extension is disabled when it is installed and enabled in remote server', async () => {
|
||||
// multi server setup
|
||||
const gallery = aGalleryExtension('a');
|
||||
const localExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file('pub.a') });
|
||||
const localExtensionManagementService = createExtensionManagementService([localExtension]);
|
||||
const onDidInstallEvent = new Emitter<DidInstallExtensionEvent>();
|
||||
localExtensionManagementService.onDidInstallExtension = onDidInstallEvent.event;
|
||||
const remoteExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file('pub.a').with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, localExtensionManagementService, createExtensionManagementService([remoteExtension]));
|
||||
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
|
||||
instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
|
||||
const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
|
||||
instantiationService.set(IExtensionsWorkbenchService, workbenchService);
|
||||
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve([ExtensionsActions.toExtensionDescription(remoteExtension)]),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.localExtensionManagementServer!);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.extension);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test remote install action is enabled for local workspace extension', async () => {
|
||||
@@ -1854,7 +1915,7 @@ suite('ExtensionsActions Test', () => {
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test local install action is enabled for remote ui extension', async () => {
|
||||
test('Test local install action is disabled for remote ui extension', async () => {
|
||||
// multi server setup
|
||||
const remoteUIExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService(), createExtensionManagementService([remoteUIExtension]));
|
||||
@@ -1870,9 +1931,7 @@ suite('ExtensionsActions Test', () => {
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Install Locally', testObject.label);
|
||||
assert.equal('extension-action prominent install', testObject.class);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test local install action when installing remote ui extension', async () => {
|
||||
@@ -1896,54 +1955,10 @@ suite('ExtensionsActions Test', () => {
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Install Locally', testObject.label);
|
||||
assert.equal('extension-action prominent install', testObject.class);
|
||||
|
||||
onInstallExtension.fire({ identifier: remoteUIExtension.identifier, gallery });
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Installing', testObject.label);
|
||||
assert.equal('extension-action install installing', testObject.class);
|
||||
});
|
||||
|
||||
test('Test local install action when installing remote ui extension is finished', async () => {
|
||||
// multi server setup
|
||||
const localExtensionManagementService: IExtensionManagementService = createExtensionManagementService();
|
||||
const onInstallExtension = new Emitter<InstallExtensionEvent>();
|
||||
localExtensionManagementService.onInstallExtension = onInstallExtension.event;
|
||||
const onDidInstallEvent = new Emitter<DidInstallExtensionEvent>();
|
||||
localExtensionManagementService.onDidInstallExtension = onDidInstallEvent.event;
|
||||
const remoteUIExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, localExtensionManagementService, createExtensionManagementService([remoteUIExtension]));
|
||||
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
|
||||
instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
|
||||
const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
|
||||
instantiationService.stub(IExtensionsWorkbenchService, workbenchService, 'open', undefined);
|
||||
instantiationService.set(IExtensionsWorkbenchService, workbenchService);
|
||||
|
||||
const gallery = aGalleryExtension('a', { identifier: remoteUIExtension.identifier });
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.LocalInstallAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Install Locally', testObject.label);
|
||||
assert.equal('extension-action prominent install', testObject.class);
|
||||
|
||||
onInstallExtension.fire({ identifier: remoteUIExtension.identifier, gallery });
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Installing', testObject.label);
|
||||
assert.equal('extension-action install installing', testObject.class);
|
||||
|
||||
const installedExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file(`pub.a`) });
|
||||
onDidInstallEvent.fire({ identifier: installedExtension.identifier, local: installedExtension, operation: InstallOperation.Install });
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test local install action is enabled for disabled remote ui extension', async () => {
|
||||
test('Test local install action is disabled for disabled remote ui extension', async () => {
|
||||
// multi server setup
|
||||
const remoteUIExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService(), createExtensionManagementService([remoteUIExtension]));
|
||||
@@ -1960,9 +1975,7 @@ suite('ExtensionsActions Test', () => {
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Install Locally', testObject.label);
|
||||
assert.equal('extension-action prominent install', testObject.class);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test local install action is disabled when extension is not set', async () => {
|
||||
@@ -2062,7 +2075,7 @@ suite('ExtensionsActions Test', () => {
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test local install action is disabled for remoteUI extension if it is uninstalled locally', async () => {
|
||||
test('Test local install action is disabled for remote UI extension if it uninstalled locally', async () => {
|
||||
// multi server setup
|
||||
const extensionManagementService = instantiationService.get(IExtensionManagementService);
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService(), extensionManagementService);
|
||||
@@ -2080,14 +2093,13 @@ suite('ExtensionsActions Test', () => {
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Install Locally', testObject.label);
|
||||
assert.ok(!testObject.enabled);
|
||||
|
||||
uninstallEvent.fire(remoteUIExtension.identifier);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test local install action is enabled for remote UI extension if it has gallery', async () => {
|
||||
test('Test local install action is disabled for remote UI extension if it has gallery', async () => {
|
||||
// multi server setup
|
||||
const remoteUIExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService(), createExtensionManagementService([remoteUIExtension]));
|
||||
@@ -2103,7 +2115,7 @@ suite('ExtensionsActions Test', () => {
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.extension);
|
||||
assert.ok(testObject.enabled);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test local install action is disabled for remote UI system extension', async () => {
|
||||
|
||||
Reference in New Issue
Block a user