mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-30 08:40:29 -04:00
Merge from vscode 0fde6619172c9f04c41f2e816479e432cc974b8b (#5199)
This commit is contained in:
@@ -11,6 +11,8 @@ import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IUntitledResourceInput } from 'vs/workbench/common/editor';
|
||||
import { toLocalResource } from 'vs/base/common/resources';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
export class BackupRestorer implements IWorkbenchContribution {
|
||||
|
||||
@@ -21,7 +23,8 @@ export class BackupRestorer implements IWorkbenchContribution {
|
||||
constructor(
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IBackupFileService private readonly backupFileService: IBackupFileService,
|
||||
@ILifecycleService private readonly lifecycleService: ILifecycleService
|
||||
@ILifecycleService private readonly lifecycleService: ILifecycleService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
this.restoreBackups();
|
||||
}
|
||||
@@ -79,9 +82,9 @@ export class BackupRestorer implements IWorkbenchContribution {
|
||||
if (resource.scheme === Schemas.untitled
|
||||
&& !BackupRestorer.UNTITLED_REGEX.test(resource.fsPath)
|
||||
&& !BackupRestorer.SQLQUERY_REGEX.test(resource.fsPath)) {
|
||||
return { filePath: resource.fsPath, options };
|
||||
return { resource: toLocalResource(resource, this.environmentService.configuration.remoteAuthority), options, forceUntitled: true };
|
||||
}
|
||||
|
||||
return { resource, options };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ export interface IExtensionsWorkbenchService {
|
||||
_serviceBrand: any;
|
||||
onChange: Event<IExtension | undefined>;
|
||||
local: IExtension[];
|
||||
installed: IExtension[];
|
||||
outdated: IExtension[];
|
||||
queryLocal(server?: IExtensionManagementServer): Promise<IExtension[]>;
|
||||
queryGallery(token: CancellationToken): Promise<IPager<IExtension>>;
|
||||
|
||||
@@ -28,7 +28,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension
|
||||
import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget } from 'vs/workbench/contrib/extensions/electron-browser/extensionsWidgets';
|
||||
import { EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, DisabledLabelAction, SystemDisabledWarningAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions';
|
||||
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, DisabledLabelAction, SystemDisabledWarningAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions';
|
||||
import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
@@ -300,7 +300,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
this.extensionManifest = new Cache(() => createCancelablePromise(token => extension.getManifest(token)));
|
||||
this.extensionDependencies = new Cache(() => createCancelablePromise(token => this.extensionsWorkbenchService.loadDependencies(extension, token)));
|
||||
|
||||
const remoteBadge = this.instantiationService.createInstance(RemoteBadgeWidget, this.iconContainer);
|
||||
const remoteBadge = this.instantiationService.createInstance(RemoteBadgeWidget, this.iconContainer, true);
|
||||
const onError = Event.once(domEvent(this.icon, 'error'));
|
||||
onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables);
|
||||
this.icon.src = extension.iconUrl;
|
||||
@@ -393,6 +393,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
this.instantiationService.createInstance(EnableDropDownAction),
|
||||
this.instantiationService.createInstance(DisableDropDownAction, runningExtensions),
|
||||
this.instantiationService.createInstance(RemoteInstallAction),
|
||||
this.instantiationService.createInstance(LocalInstallAction),
|
||||
combinedInstallAction,
|
||||
systemDisabledWarningAction,
|
||||
this.instantiationService.createInstance(DisabledLabelAction, systemDisabledWarningAction),
|
||||
|
||||
@@ -316,12 +316,14 @@ export class RemoteInstallAction extends ExtensionAction {
|
||||
private updateLabel(): void {
|
||||
if (this.installing) {
|
||||
this.label = RemoteInstallAction.INSTALLING_LABEL;
|
||||
this.tooltip = this.label;
|
||||
return;
|
||||
}
|
||||
const remoteAuthority = this.environmentService.configuration.remoteAuthority;
|
||||
if (remoteAuthority) {
|
||||
const host = this.labelService.getHostLabel(REMOTE_HOST_SCHEME, this.environmentService.configuration.remoteAuthority) || localize('remote', "Remote");
|
||||
this.label = `${RemoteInstallAction.INSTALL_LABEL} on ${host}`;
|
||||
this.tooltip = this.label;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -339,9 +341,9 @@ export class RemoteInstallAction extends ExtensionAction {
|
||||
// Installed User Extension
|
||||
&& this.extension && this.extension.local && this.extension.type === ExtensionType.User && this.extension.state === ExtensionState.Installed
|
||||
// Local Workspace Extension
|
||||
&& this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && !isUIExtension(this.extension.local.manifest, this.configurationService)
|
||||
&& this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && (isLanguagePackExtension(this.extension.local.manifest) || !isUIExtension(this.extension.local.manifest, this.configurationService))
|
||||
// Extension does not exist in remote
|
||||
&& !this.extensionsWorkbenchService.local.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.remoteExtensionManagementServer)
|
||||
&& !this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.remoteExtensionManagementServer)
|
||||
&& this.extensionsWorkbenchService.canInstall(this.extension)
|
||||
) {
|
||||
this.enabled = true;
|
||||
@@ -370,6 +372,85 @@ export class RemoteInstallAction extends ExtensionAction {
|
||||
}
|
||||
}
|
||||
|
||||
export class LocalInstallAction extends ExtensionAction {
|
||||
|
||||
private static INSTALL_LABEL = localize('install locally', "Install Locally");
|
||||
private static INSTALLING_LABEL = localize('installing', "Installing");
|
||||
|
||||
private static readonly Class = 'extension-action prominent install';
|
||||
private static readonly InstallingClass = 'extension-action install installing';
|
||||
|
||||
updateWhenCounterExtensionChanges: boolean = true;
|
||||
private disposables: IDisposable[] = [];
|
||||
private installing: boolean = false;
|
||||
|
||||
constructor(
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
) {
|
||||
super(`extensions.localinstall`, LocalInstallAction.INSTALL_LABEL, LocalInstallAction.Class, false);
|
||||
this.labelService.onDidChangeFormatters(() => this.updateLabel(), this, this.disposables);
|
||||
this.updateLabel();
|
||||
this.update();
|
||||
}
|
||||
|
||||
private updateLabel(): void {
|
||||
if (this.installing) {
|
||||
this.label = LocalInstallAction.INSTALLING_LABEL;
|
||||
this.tooltip = this.label;
|
||||
return;
|
||||
}
|
||||
this.label = `${LocalInstallAction.INSTALL_LABEL}`;
|
||||
this.tooltip = this.label;
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.enabled = false;
|
||||
this.class = LocalInstallAction.Class;
|
||||
if (this.installing) {
|
||||
this.enabled = true;
|
||||
this.class = LocalInstallAction.InstallingClass;
|
||||
this.updateLabel();
|
||||
return;
|
||||
}
|
||||
if (this.environmentService.configuration.remoteAuthority
|
||||
// Installed User Extension
|
||||
&& this.extension && this.extension.local && this.extension.type === ExtensionType.User && this.extension.state === ExtensionState.Installed
|
||||
// Remote UI or Language pack Extension
|
||||
&& this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && (isLanguagePackExtension(this.extension.local.manifest) || isUIExtension(this.extension.local.manifest, this.configurationService))
|
||||
// Extension does not exist in local
|
||||
&& !this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.localExtensionManagementServer)
|
||||
&& this.extensionsWorkbenchService.canInstall(this.extension)
|
||||
) {
|
||||
this.enabled = true;
|
||||
this.updateLabel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
if (!this.installing) {
|
||||
this.installing = true;
|
||||
this.update();
|
||||
this.extensionsWorkbenchService.open(this.extension);
|
||||
alert(localize('installExtensionStart', "Installing extension {0} started. An editor is now open with more details on this extension", this.extension.displayName));
|
||||
if (this.extension.gallery) {
|
||||
await this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(this.extension.gallery);
|
||||
this.installing = false;
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class UninstallAction extends ExtensionAction {
|
||||
|
||||
private static readonly UninstallLabel = localize('uninstallAction', "Uninstall");
|
||||
@@ -1265,23 +1346,34 @@ export class ReloadAction extends ExtensionAction {
|
||||
if (isEnabled && !this.extensionService.canAddExtension(toExtensionDescription(this.extension.local))) {
|
||||
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.");
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension."); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
return;
|
||||
}
|
||||
if (this.workbenchEnvironmentService.configuration.remoteAuthority
|
||||
if (this.workbenchEnvironmentService.configuration.remoteAuthority) {
|
||||
const uiExtension = isUIExtension(this.extension.local.manifest, this.configurationService);
|
||||
// Local Workspace Extension
|
||||
&& this.extension.server === this.extensionManagementServerService.localExtensionManagementServer && !isUIExtension(this.extension.local.manifest, this.configurationService)
|
||||
) {
|
||||
const remoteExtension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.remoteExtensionManagementServer)[0];
|
||||
// Extension exist in remote and enabled
|
||||
if (remoteExtension && remoteExtension.local && this.extensionEnablementService.isEnabled(remoteExtension.local)) {
|
||||
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.");
|
||||
alert(localize('installExtensionComplete', "Installing extension {0} is completed. Please reload Azure Data Studio to enable it.", this.extension.displayName));
|
||||
return;
|
||||
if (!uiExtension && this.extension.server === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
const remoteExtension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.remoteExtensionManagementServer)[0];
|
||||
// Extension exist in remote and enabled
|
||||
if (remoteExtension && remoteExtension.local && this.extensionEnablementService.isEnabled(remoteExtension.local)) {
|
||||
this.enabled = true;
|
||||
this.label = localize('reloadRequired', "Reload Required");
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension.");// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
alert(localize('installExtensionComplete', "Installing extension {0} is completed. Please reload Azure Data Studio to enable it.", this.extension.displayName)); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Remote UI Extension
|
||||
if (uiExtension && this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const localExtension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.localExtensionManagementServer)[0];
|
||||
// Extension exist in local and enabled
|
||||
if (localExtension && localExtension.local && this.extensionEnablementService.isEnabled(localExtension.local)) {
|
||||
this.enabled = true;
|
||||
this.label = localize('reloadRequired', "Reload Required");
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension."); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
alert(localize('installExtensionComplete', "Installing extension {0} is completed. Please reload Azure Data Studio to enable it.", this.extension.displayName)); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2464,7 +2556,8 @@ export class StatusLabelAction extends Action implements IExtensionContainer {
|
||||
}
|
||||
|
||||
constructor(
|
||||
@IExtensionService private readonly extensionService: IExtensionService
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
|
||||
) {
|
||||
super('extensions.action.statusLabel', '', StatusLabelAction.DISABLED_CLASS, false);
|
||||
}
|
||||
@@ -2503,7 +2596,7 @@ export class StatusLabelAction extends Action implements IExtensionContainer {
|
||||
};
|
||||
const canRemoveExtension = () => {
|
||||
if (this.extension.local) {
|
||||
if (runningExtensions.every(e => !areSameExtensions({ id: e.identifier.value }, this.extension.identifier))) {
|
||||
if (runningExtensions.every(e => !(areSameExtensions({ id: e.identifier.value }, this.extension.identifier) && this.extension.server === this.extensionManagementServerService.getExtensionManagementServer(e.extensionLocation)))) {
|
||||
return true;
|
||||
}
|
||||
return this.extensionService.canRemoveExtension(toExtensionDescription(this.extension.local));
|
||||
@@ -2592,21 +2685,18 @@ export class DisabledLabelAction extends ExtensionAction {
|
||||
update(): void {
|
||||
this.class = `${DisabledLabelAction.Class} hide`;
|
||||
this.label = '';
|
||||
this.enabled = false;
|
||||
if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
return;
|
||||
}
|
||||
if (this.warningAction.enabled) {
|
||||
this.enabled = true;
|
||||
if (this.warningAction.tooltip) {
|
||||
this.class = DisabledLabelAction.Class;
|
||||
this.label = this.warningAction.tooltip;
|
||||
return;
|
||||
}
|
||||
if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
return;
|
||||
}
|
||||
if (this.extension && this.extension.local && this._runningExtensions) {
|
||||
const isEnabled = this.extensionEnablementService.isEnabled(this.extension.local);
|
||||
const isExtensionRunning = this._runningExtensions.some(e => areSameExtensions({ id: e.identifier.value }, this.extension.identifier));
|
||||
if (!isExtensionRunning && !isEnabled) {
|
||||
this.enabled = true;
|
||||
if (!isExtensionRunning && !isEnabled && this.extensionEnablementService.canChangeEnablement(this.extension.local)) {
|
||||
this.class = DisabledLabelAction.Class;
|
||||
this.label = localize('disabled by user', "This extension is disabled by the user.");
|
||||
return;
|
||||
@@ -2626,7 +2716,9 @@ export class DisabledLabelAction extends ExtensionAction {
|
||||
|
||||
export class SystemDisabledWarningAction extends ExtensionAction {
|
||||
|
||||
private static readonly Class = 'disable-warning';
|
||||
private static readonly CLASS = 'system-disable';
|
||||
private static readonly WARNING_CLASS = `${SystemDisabledWarningAction.CLASS} warning`;
|
||||
private static readonly INFO_CLASS = `${SystemDisabledWarningAction.CLASS} info`;
|
||||
|
||||
updateWhenCounterExtensionChanges: boolean = true;
|
||||
private disposables: IDisposable[] = [];
|
||||
@@ -2640,7 +2732,7 @@ export class SystemDisabledWarningAction extends ExtensionAction {
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
) {
|
||||
super('extensions.install', '', `${SystemDisabledWarningAction.Class} hide`, false);
|
||||
super('extensions.install', '', `${SystemDisabledWarningAction.CLASS} hide`, false);
|
||||
this.labelService.onDidChangeFormatters(() => this.update(), this, this.disposables);
|
||||
this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this, this.disposables);
|
||||
this.updateRunningExtensions();
|
||||
@@ -2652,44 +2744,54 @@ export class SystemDisabledWarningAction extends ExtensionAction {
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.enabled = false;
|
||||
this.class = `${SystemDisabledWarningAction.Class} hide`;
|
||||
this.class = `${SystemDisabledWarningAction.CLASS} hide`;
|
||||
this.tooltip = '';
|
||||
if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
if (
|
||||
!this.extension ||
|
||||
!this.extension.local ||
|
||||
!this.extension.server ||
|
||||
!this._runningExtensions ||
|
||||
!this.workbenchEnvironmentService.configuration.remoteAuthority ||
|
||||
!this.extensionManagementServerService.remoteExtensionManagementServer ||
|
||||
this.extension.state !== ExtensionState.Installed
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (this.extension && this.extension.local && this.extension.server && this._runningExtensions && this.workbenchEnvironmentService.configuration.remoteAuthority && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value }, 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.configurationService)) {
|
||||
if (runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
this.enabled = true;
|
||||
this.class = `${SystemDisabledWarningAction.Class}`;
|
||||
this.tooltip = localize('disabled locally', "Extension is enabled on '{0}' and disabled locally.", this.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer));
|
||||
return;
|
||||
}
|
||||
if (localExtensionServer !== this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
this.enabled = true;
|
||||
this.class = `${SystemDisabledWarningAction.Class}`;
|
||||
this.tooltip = localize('Install in remote server', "Install the extension on '{0}' to enable.", this.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer));
|
||||
return;
|
||||
}
|
||||
if (isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
if (!this.extensionsWorkbenchService.installed.some(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server !== this.extension.server)) {
|
||||
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;
|
||||
this.tooltip = this.extension.server === this.extensionManagementServerService.localExtensionManagementServer
|
||||
? localize('Install language pack also in remote server', "Install the language pack extension on '{0}' to enable it also there.", this.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer))
|
||||
: localize('Install language pack also locally', "Install the language pack extension locally to enable it also there.");
|
||||
}
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && isUIExtension(this.extension.local.manifest, this.configurationService)) {
|
||||
if (runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
this.enabled = true;
|
||||
this.class = `${SystemDisabledWarningAction.Class}`;
|
||||
this.tooltip = localize('disabled remotely', "Extension is enabled locally and disabled on '{0}'.", this.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer));
|
||||
return;
|
||||
}
|
||||
if (localExtensionServer !== this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
this.enabled = true;
|
||||
this.class = `${SystemDisabledWarningAction.Class}`;
|
||||
this.tooltip = localize('Install in local server', "Install the extension locally to enable.");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const runningExtension = this._runningExtensions.filter(e => areSameExtensions({ id: e.identifier.value }, 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.configurationService)) {
|
||||
if (runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;
|
||||
this.tooltip = localize('disabled locally', "Extension is enabled on '{0}' and disabled locally.", this.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer));
|
||||
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.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && isUIExtension(this.extension.local.manifest, this.configurationService)) {
|
||||
if (runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
this.class = `${SystemDisabledWarningAction.INFO_CLASS}`;
|
||||
this.tooltip = localize('disabled remotely', "Extension is enabled locally and disabled on '{0}'.", this.getServerLabel(this.extensionManagementServerService.remoteExtensionManagementServer));
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
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, ExtensionActionItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, DisabledLabelAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions';
|
||||
import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, DisabledLabelAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget } from 'vs/workbench/contrib/extensions/electron-browser/extensionsWidgets';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -67,7 +67,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
const element = append(root, $('.extension'));
|
||||
const iconContainer = append(element, $('.icon-container'));
|
||||
const icon = append(iconContainer, $<HTMLImageElement>('img.icon'));
|
||||
const iconRemoteBadgeWidget = this.instantiationService.createInstance(RemoteBadgeWidget, iconContainer);
|
||||
const iconRemoteBadgeWidget = this.instantiationService.createInstance(RemoteBadgeWidget, iconContainer, false);
|
||||
const details = append(element, $('.details'));
|
||||
const headerContainer = append(details, $('.header-container'));
|
||||
const header = append(headerContainer, $('.header'));
|
||||
@@ -75,7 +75,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
const version = append(header, $('span.version'));
|
||||
const installCount = append(header, $('span.install-count'));
|
||||
const ratings = append(header, $('span.ratings'));
|
||||
const headerRemoteBadgeWidget = this.instantiationService.createInstance(RemoteBadgeWidget, header);
|
||||
const headerRemoteBadgeWidget = this.instantiationService.createInstance(RemoteBadgeWidget, header, false);
|
||||
const description = append(details, $('.description.ellipsis'));
|
||||
const footer = append(details, $('.footer'));
|
||||
const author = append(footer, $('.author.ellipsis'));
|
||||
@@ -98,6 +98,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
reloadAction,
|
||||
this.instantiationService.createInstance(InstallAction),
|
||||
this.instantiationService.createInstance(RemoteInstallAction),
|
||||
this.instantiationService.createInstance(LocalInstallAction),
|
||||
this.instantiationService.createInstance(MaliciousStatusLabelAction, false),
|
||||
systemDisabledWarningAction,
|
||||
this.instantiationService.createInstance(ManageExtensionAction)
|
||||
|
||||
@@ -55,6 +55,9 @@ import { ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { RemoteAuthorityContext } from 'vs/workbench/common/contextkeys';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
|
||||
interface SearchInputEvent extends Event {
|
||||
target: HTMLInputElement;
|
||||
@@ -91,7 +94,9 @@ const viewIdNameMappings: { [id: string]: string } = {
|
||||
export class ExtensionsViewletViewsContribution implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
this.registerViews();
|
||||
}
|
||||
@@ -180,22 +185,32 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
*/
|
||||
|
||||
private createExtensionsViewDescriptorsForServer(server: IExtensionManagementServer): IViewDescriptor[] {
|
||||
const getViewName = (viewTitle: string, server: IExtensionManagementServer): string => {
|
||||
const serverLabel = this.workbenchEnvironmentService.configuration.remoteAuthority === server.authority ? this.labelService.getHostLabel(REMOTE_HOST_SCHEME, server.authority) || server.label : server.label;
|
||||
if (viewTitle && this.workbenchEnvironmentService.configuration.remoteAuthority) {
|
||||
return `${serverLabel} - ${viewTitle}`;
|
||||
}
|
||||
return viewTitle ? viewTitle : serverLabel;
|
||||
};
|
||||
const getInstalledViewName = (): string => getViewName(localize('installed', "Installed"), server);
|
||||
const getOutdatedViewName = (): string => getViewName(localize('outdated', "Outdated"), server);
|
||||
const onDidChangeServerLabel: EventOf<void> = this.workbenchEnvironmentService.configuration.remoteAuthority ? EventOf.map(this.labelService.onDidChangeFormatters, () => undefined) : EventOf.None;
|
||||
return [{
|
||||
id: `extensions.${server.authority}.installed`,
|
||||
name: localize('installed', "Installed"),
|
||||
ctorDescriptor: { ctor: ServerExtensionsView, arguments: [server] },
|
||||
get name() { return getInstalledViewName(); },
|
||||
ctorDescriptor: { ctor: ServerExtensionsView, arguments: [server, EventOf.map<void, string>(onDidChangeServerLabel, () => getInstalledViewName())] },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('searchInstalledExtensions')),
|
||||
weight: 100
|
||||
}, {
|
||||
id: `extensions.${server.authority}.outdated`,
|
||||
name: localize('outdated', "Outdated"),
|
||||
ctorDescriptor: { ctor: ServerExtensionsView, arguments: [server] },
|
||||
get name() { return getOutdatedViewName(); },
|
||||
ctorDescriptor: { ctor: ServerExtensionsView, arguments: [server, EventOf.map<void, string>(onDidChangeServerLabel, () => getOutdatedViewName())] },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('searchOutdatedExtensions')),
|
||||
weight: 100
|
||||
}, {
|
||||
id: `extensions.${server.authority}.default`,
|
||||
name: localize('installed', "Installed"),
|
||||
ctorDescriptor: { ctor: ServerExtensionsView, arguments: [server] },
|
||||
get name() { return getInstalledViewName(); },
|
||||
ctorDescriptor: { ctor: ServerExtensionsView, arguments: [server, EventOf.map<void, string>(onDidChangeServerLabel, () => getInstalledViewName())] },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('defaultExtensionViews'), ContextKeyExpr.has('hasInstalledExtensions'), RemoteAuthorityContext.notEqualsTo('')),
|
||||
weight: 40,
|
||||
order: 1
|
||||
@@ -228,7 +243,6 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
ctorDescriptor: { ctor: RecommendedExtensionsView },
|
||||
when: ContextKeyExpr.has('recommendedExtensions'),
|
||||
weight: 50,
|
||||
canToggleVisibility: true,
|
||||
order: 2
|
||||
};
|
||||
}
|
||||
@@ -243,7 +257,6 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
ctorDescriptor: { ctor: WorkspaceRecommendedExtensionsView },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('recommendedExtensions'), ContextKeyExpr.has('nonEmptyWorkspace')),
|
||||
weight: 50,
|
||||
canToggleVisibility: true,
|
||||
order: 1
|
||||
};
|
||||
}
|
||||
@@ -256,7 +269,6 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
ctorDescriptor: { ctor: EnabledExtensionsView },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('searchEnabledExtensions')),
|
||||
weight: 40,
|
||||
canToggleVisibility: true,
|
||||
order: 1
|
||||
};
|
||||
}
|
||||
@@ -269,7 +281,6 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
ctorDescriptor: { ctor: DisabledExtensionsView },
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has('searchDisabledExtensions')),
|
||||
weight: 10,
|
||||
canToggleVisibility: true,
|
||||
order: 3,
|
||||
collapsed: true
|
||||
};
|
||||
@@ -282,8 +293,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
name: viewIdNameMappings[id],
|
||||
ctorDescriptor: { ctor: BuiltInExtensionsView },
|
||||
when: ContextKeyExpr.has('searchBuiltInExtensions'),
|
||||
weight: 100,
|
||||
canToggleVisibility: true
|
||||
weight: 100
|
||||
};
|
||||
}
|
||||
|
||||
@@ -294,8 +304,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
name: viewIdNameMappings[id],
|
||||
ctorDescriptor: { ctor: BuiltInThemesExtensionsView },
|
||||
when: ContextKeyExpr.has('searchBuiltInExtensions'),
|
||||
weight: 100,
|
||||
canToggleVisibility: true
|
||||
weight: 100
|
||||
};
|
||||
}
|
||||
|
||||
@@ -306,8 +315,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio
|
||||
name: viewIdNameMappings[id],
|
||||
ctorDescriptor: { ctor: BuiltInBasicsExtensionsView },
|
||||
when: ContextKeyExpr.has('searchBuiltInExtensions'),
|
||||
weight: 100,
|
||||
canToggleVisibility: true
|
||||
weight: 100
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { append, $, toggleClass } from 'vs/base/browser/dom';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Delegate, Renderer, IExtensionsViewState } from 'vs/workbench/contrib/extensions/electron-browser/extensionsList';
|
||||
import { IExtension, IExtensionsWorkbenchService } from '../common/extensions';
|
||||
import { IExtension, IExtensionsWorkbenchService, ExtensionState } from '../common/extensions';
|
||||
import { Query } from '../common/extensionQuery';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -45,9 +45,7 @@ import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePa
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { isUIExtension } from 'vs/workbench/services/extensions/node/extensionsUtil';
|
||||
|
||||
class ExtensionsViewState extends Disposable implements IExtensionsViewState {
|
||||
|
||||
@@ -97,7 +95,7 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
@IWorkspaceContextService protected contextService: IWorkspaceContextService,
|
||||
@IExperimentService private readonly experimentService: IExperimentService,
|
||||
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
|
||||
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService
|
||||
) {
|
||||
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService);
|
||||
this.server = options.server;
|
||||
@@ -340,11 +338,20 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
const isE1Running = running1 && this.extensionManagementServerService.getExtensionManagementServer(running1.extensionLocation) === e1.server;
|
||||
const running2 = runningExtensionsById.get(ExtensionIdentifier.toKey(e2.identifier.id));
|
||||
const isE2Running = running2 && this.extensionManagementServerService.getExtensionManagementServer(running2.extensionLocation) === e2.server;
|
||||
if ((isE1Running && isE2Running) || (!isE1Running && !isE2Running)) {
|
||||
if ((isE1Running && isE2Running)) {
|
||||
return e1.displayName.localeCompare(e2.displayName);
|
||||
}
|
||||
const isE1LanguagePackExtension = e1.local && isLanguagePackExtension(e1.local.manifest);
|
||||
const isE2LanguagePackExtension = e2.local && isLanguagePackExtension(e2.local.manifest);
|
||||
if (!isE1Running && !isE2Running) {
|
||||
if (isE1LanguagePackExtension) {
|
||||
return -1;
|
||||
}
|
||||
if (isE2LanguagePackExtension) {
|
||||
return 1;
|
||||
}
|
||||
return e1.displayName.localeCompare(e2.displayName);
|
||||
}
|
||||
if ((isE1Running && isE2LanguagePackExtension) || (isE2Running && isE1LanguagePackExtension)) {
|
||||
return e1.displayName.localeCompare(e2.displayName);
|
||||
}
|
||||
@@ -865,18 +872,11 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
}
|
||||
}
|
||||
|
||||
function getViewTitleForServer(viewTitle: string, server: IExtensionManagementServer, labelService: ILabelService, workbenchEnvironmentService: IWorkbenchEnvironmentService): string {
|
||||
const serverLabel = workbenchEnvironmentService.configuration.remoteAuthority === server.authority ? labelService.getHostLabel(REMOTE_HOST_SCHEME, server.authority) || server.label : server.label;
|
||||
if (viewTitle && workbenchEnvironmentService.configuration.remoteAuthority) {
|
||||
return `${serverLabel} - ${viewTitle}`;
|
||||
}
|
||||
return viewTitle ? viewTitle : serverLabel;
|
||||
}
|
||||
|
||||
export class ServerExtensionsView extends ExtensionsListView {
|
||||
|
||||
constructor(
|
||||
server: IExtensionManagementServer,
|
||||
onDidChangeTitle: Event<string>,
|
||||
options: ExtensionsListViewOptions,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@@ -893,15 +893,11 @@ export class ServerExtensionsView extends ExtensionsListView {
|
||||
@IExperimentService experimentService: IExperimentService,
|
||||
@IWorkbenchThemeService workbenchThemeService: IWorkbenchThemeService,
|
||||
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
@IWorkbenchEnvironmentService workbenchEnvironmentService: IWorkbenchEnvironmentService,
|
||||
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService
|
||||
) {
|
||||
const viewTitle = options.title;
|
||||
options.title = getViewTitleForServer(viewTitle, server, labelService, workbenchEnvironmentService);
|
||||
options.server = server;
|
||||
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, modeService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService);
|
||||
this.disposables.push(labelService.onDidChangeFormatters(() => this.updateTitle(getViewTitleForServer(viewTitle, server, labelService, workbenchEnvironmentService))));
|
||||
this.disposables.push(onDidChangeTitle(title => this.updateTitle(title)));
|
||||
}
|
||||
|
||||
async show(query: string): Promise<IPagedModel<IExtension>> {
|
||||
@@ -1044,6 +1040,12 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView {
|
||||
|
||||
private getRecommendationsToInstall(): Promise<IExtensionRecommendation[]> {
|
||||
return this.tipsService.getWorkspaceRecommendations()
|
||||
.then(recommendations => recommendations.filter(({ extensionId }) => !this.extensionsWorkbenchService.local.some(i => areSameExtensions({ id: extensionId }, i.identifier))));
|
||||
.then(recommendations => recommendations.filter(({ extensionId }) => {
|
||||
const extension = this.extensionsWorkbenchService.local.filter(i => areSameExtensions({ id: extensionId }, i.identifier))[0];
|
||||
if (!extension || !extension.local || extension.state !== ExtensionState.Installed) {
|
||||
return true;
|
||||
}
|
||||
return isUIExtension(extension.local.manifest, this.configurationService) ? extension.server !== this.extensionManagementServerService.localExtensionManagementServer : extension.server !== this.extensionManagementServerService.remoteExtensionManagementServer;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import 'vs/css!./media/extensionsWidgets';
|
||||
import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IExtension, IExtensionsWorkbenchService, IExtensionContainer } from '../common/extensions';
|
||||
import { IExtension, IExtensionsWorkbenchService, IExtensionContainer, ExtensionState } from '../common/extensions';
|
||||
import { append, $, addClass } from 'vs/base/browser/dom';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -148,34 +148,46 @@ export class TooltipWidget extends ExtensionWidget {
|
||||
|
||||
constructor(
|
||||
private readonly parent: HTMLElement,
|
||||
private readonly extensionLabelAction: DisabledLabelAction,
|
||||
private readonly disabledLabelAction: DisabledLabelAction,
|
||||
private readonly recommendationWidget: RecommendationWidget,
|
||||
private readonly reloadAction: ReloadAction
|
||||
private readonly reloadAction: ReloadAction,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
super();
|
||||
this._register(Event.any<any>(
|
||||
this.extensionLabelAction.onDidChange,
|
||||
this.disabledLabelAction.onDidChange,
|
||||
this.reloadAction.onDidChange,
|
||||
this.recommendationWidget.onDidChangeTooltip
|
||||
this.recommendationWidget.onDidChangeTooltip,
|
||||
this.labelService.onDidChangeFormatters
|
||||
)(() => this.render()));
|
||||
}
|
||||
|
||||
render(): void {
|
||||
this.parent.title = '';
|
||||
this.parent.removeAttribute('aria-label');
|
||||
this.parent.title = this.getTooltip();
|
||||
if (this.extension) {
|
||||
const title = this.getTitle();
|
||||
this.parent.title = title;
|
||||
this.parent.setAttribute('aria-label', localize('extension-arialabel', "{0}. {1} Press enter for extension details.", this.extension.displayName));
|
||||
}
|
||||
}
|
||||
|
||||
private getTitle(): string {
|
||||
private getTooltip(): string {
|
||||
if (!this.extension) {
|
||||
return '';
|
||||
}
|
||||
if (this.reloadAction.enabled) {
|
||||
return this.reloadAction.tooltip;
|
||||
}
|
||||
if (this.extensionLabelAction.enabled) {
|
||||
return this.extensionLabelAction.label;
|
||||
if (this.disabledLabelAction.label) {
|
||||
return this.disabledLabelAction.label;
|
||||
}
|
||||
if (this.extension.local && this.extension.state === ExtensionState.Installed) {
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return localize('extension enabled on remote', "Extension is enabled on '{0}'", this.labelService.getHostLabel(REMOTE_HOST_SCHEME, this.workbenchEnvironmentService.configuration.remoteAuthority));
|
||||
}
|
||||
return localize('extension enabled locally', "Extension is enabled locally.");
|
||||
}
|
||||
return this.recommendationWidget.tooltip;
|
||||
}
|
||||
@@ -252,6 +264,7 @@ export class RemoteBadgeWidget extends ExtensionWidget {
|
||||
|
||||
constructor(
|
||||
parent: HTMLElement,
|
||||
private readonly tooltip: boolean,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
@@ -276,7 +289,7 @@ export class RemoteBadgeWidget extends ExtensionWidget {
|
||||
return;
|
||||
}
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
this.remoteBadge = this.instantiationService.createInstance(RemoteBadge);
|
||||
this.remoteBadge = this.instantiationService.createInstance(RemoteBadge, this.tooltip);
|
||||
append(this.element, this.remoteBadge.element);
|
||||
}
|
||||
}
|
||||
@@ -294,6 +307,7 @@ class RemoteBadge extends Disposable {
|
||||
readonly element: HTMLElement;
|
||||
|
||||
constructor(
|
||||
private readonly tooltip: boolean,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
|
||||
@@ -320,12 +334,14 @@ class RemoteBadge extends Disposable {
|
||||
this._register(this.themeService.onThemeChange(() => applyBadgeStyle()));
|
||||
this._register(this.workspaceContextService.onDidChangeWorkbenchState(() => applyBadgeStyle()));
|
||||
|
||||
const updateTitle = () => {
|
||||
if (this.element) {
|
||||
this.element.title = localize('remote extension title', "Extension in {0}", this.labelService.getHostLabel(REMOTE_HOST_SCHEME, this.environmentService.configuration.remoteAuthority));
|
||||
}
|
||||
};
|
||||
this._register(this.labelService.onDidChangeFormatters(() => updateTitle()));
|
||||
updateTitle();
|
||||
if (this.tooltip) {
|
||||
const updateTitle = () => {
|
||||
if (this.element) {
|
||||
this.element.title = localize('remote extension title', "Extension in {0}", this.labelService.getHostLabel(REMOTE_HOST_SCHEME, this.environmentService.configuration.remoteAuthority));
|
||||
}
|
||||
};
|
||||
this._register(this.labelService.onDidChangeFormatters(() => updateTitle()));
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,9 @@
|
||||
padding: 0 5px;
|
||||
outline-offset: 2px;
|
||||
line-height: initial;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .action-label.clear-extensions {
|
||||
@@ -35,7 +38,7 @@
|
||||
.monaco-action-bar .action-item.disabled .action-label.extension-action.extension-editor-dropdown-action,
|
||||
.monaco-action-bar .action-item.disabled .action-label.extension-action.reload,
|
||||
.monaco-action-bar .action-item.disabled .action-label.disable-status.hide,
|
||||
.monaco-action-bar .action-item.disabled .action-label.disable-warning.hide,
|
||||
.monaco-action-bar .action-item.disabled .action-label.system-disable.hide,
|
||||
.monaco-action-bar .action-item.disabled .action-label.extension-status-label.hide,
|
||||
.monaco-action-bar .action-item.disabled .action-label.malicious-status.not-malicious {
|
||||
display: none;
|
||||
@@ -67,24 +70,33 @@
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .actions > .monaco-action-bar > .actions-container > .action-item > .action-label.disable-warning,
|
||||
.extensions-viewlet>.extensions .extension>.details>.footer>.monaco-action-bar .action-item .action-label.disable-warning {
|
||||
cursor: default;
|
||||
margin: 0.1em;
|
||||
.extension-editor > .header > .details > .actions > .monaco-action-bar > .actions-container > .action-item > .action-label.system-disable,
|
||||
.extensions-viewlet>.extensions .extension>.details>.footer>.monaco-action-bar .action-item .action-label.system-disable {
|
||||
margin: 0.15em;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .action-label.disable-warning.icon {
|
||||
.monaco-action-bar .action-item .action-label.system-disable.icon {
|
||||
opacity: 1;
|
||||
height: 18px;
|
||||
width: 10px;
|
||||
background: url('status-warning.svg') center center no-repeat;
|
||||
margin-top: 0.15em
|
||||
}
|
||||
|
||||
.vs-dark .monaco-action-bar .action-item .action-label.disable-warning.icon {
|
||||
.monaco-action-bar .action-item .action-label.system-disable.warning.icon {
|
||||
background: url('status-warning.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-action-bar .action-item .action-label.system-disable.warning.icon {
|
||||
background: url('status-warning-inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .action-label.system-disable.info.icon {
|
||||
background: url('status-info.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-action-bar .action-item .action-label.system-disable.info.icon {
|
||||
background: url('status-info-inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.extension-status-label,
|
||||
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.disable-status,
|
||||
.extension-editor>.header>.details>.actions>.monaco-action-bar .action-item .action-label.malicious-status {
|
||||
|
||||
@@ -41,11 +41,13 @@
|
||||
line-height: 38px;
|
||||
border-radius: 20px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .icon-container .extension-remote-badge .octicon {
|
||||
font-size: 32px;
|
||||
vertical-align: middle;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details {
|
||||
@@ -145,6 +147,9 @@
|
||||
padding: 1px 6px;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .actions > .monaco-action-bar > .actions-container > .action-item > .extension-action {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .subtext-container {
|
||||
display: block;
|
||||
|
||||
@@ -113,6 +113,10 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.extensions-viewlet > .extensions .monaco-list-row > .extension > .icon-container .extension-remote-badge > .octicon {
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.extensions-viewlet > .extensions .monaco-list-row > .extension > .details > .header-container > .header > .extension-remote-badge-container {
|
||||
margin-left: 6px;
|
||||
}
|
||||
@@ -123,11 +127,13 @@
|
||||
line-height: 14px;
|
||||
border-radius: 20px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.extensions-viewlet > .extensions .monaco-list-row > .extension > .details > .header-container > .header .extension-remote-badge > .octicon {
|
||||
font-size: 13px;
|
||||
vertical-align: middle;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.extensions-viewlet.narrow > .extensions .extension > .icon-container,
|
||||
@@ -224,6 +230,14 @@
|
||||
flex-wrap: wrap-reverse;
|
||||
}
|
||||
|
||||
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar > .actions-container .extension-action {
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.extensions-viewlet.narrow > .extensions .extension > .details > .footer > .monaco-action-bar > .actions-container .extension-action {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-label {
|
||||
margin-top: 0.3em;
|
||||
margin-left: 0.3em;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><circle cx="8.5" cy="7.5" r="5.5" fill="#1E1E1E"/><path d="M8.5 3C6.015 3 4 5.015 4 7.5S6.015 12 8.5 12 13 9.985 13 7.5 10.985 3 8.5 3zm.5 8H8V6h1v5zm0-6H8V4h1v1z" fill="#1BA1E2"/><path d="M8 6h1v5H8V6zm0-2v1h1V4H8z" fill="#252526"/></svg>
|
||||
|
After Width: | Height: | Size: 356 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><circle cx="8.5" cy="7.5" r="5.5" fill="#F6F6F6"/><path d="M8.5 3C6.015 3 4 5.015 4 7.5S6.015 12 8.5 12 13 9.985 13 7.5 10.985 3 8.5 3zm.5 8H8V6h1v5zm0-6H8V4h1v1z" fill="#1BA1E2"/><path d="M8 6h1v5H8V6zm0-2v1h1V4H8z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 353 B |
@@ -379,12 +379,12 @@ export class RuntimeExtensionsEditor extends BaseEditor {
|
||||
|
||||
if (element.description.extensionLocation.scheme !== 'file') {
|
||||
const el = $('span');
|
||||
el.innerHTML = renderOcticons(`$(rss) ${element.description.extensionLocation.authority}`);
|
||||
el.innerHTML = renderOcticons(`$(remote) ${element.description.extensionLocation.authority}`);
|
||||
data.msgContainer.appendChild(el);
|
||||
|
||||
const hostLabel = this._labelService.getHostLabel(REMOTE_HOST_SCHEME, this._environmentService.configuration.remoteAuthority);
|
||||
if (hostLabel) {
|
||||
el.innerHTML = renderOcticons(`$(rss) ${hostLabel}`);
|
||||
el.innerHTML = renderOcticons(`$(remote) ${hostLabel}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ import * as resources from 'vs/base/common/resources';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IExtensionManifest, ExtensionType, ExtensionIdentifierWithVersion, IExtension as IPlatformExtension } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionManifest, ExtensionType, ExtensionIdentifierWithVersion, IExtension as IPlatformExtension, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { isEngineValid } from 'vs/platform/extensions/node/extensionValidator';
|
||||
@@ -605,15 +605,19 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
}
|
||||
|
||||
get local(): IExtension[] {
|
||||
const result = [...this.localExtensions.local];
|
||||
if (!this.remoteExtensions) {
|
||||
return result;
|
||||
}
|
||||
result.push(...this.remoteExtensions.local);
|
||||
const result = [...this.installed];
|
||||
const byId = groupByExtension(result, r => r.identifier);
|
||||
return byId.reduce((result, extensions) => { result.push(this.getPrimaryExtension(extensions)); return result; }, []);
|
||||
}
|
||||
|
||||
get installed(): IExtension[] {
|
||||
const result = [...this.localExtensions.local];
|
||||
if (this.remoteExtensions) {
|
||||
result.push(...this.remoteExtensions.local);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
get outdated(): IExtension[] {
|
||||
const allLocal = [...this.localExtensions.local];
|
||||
if (this.remoteExtensions) {
|
||||
@@ -855,7 +859,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
}
|
||||
|
||||
return this.installWithProgress(async () => {
|
||||
// {{SQL CARBON EDIT}}
|
||||
// {{SQL CARBON EDIT}} remove extensionservice install from gallery
|
||||
if (extensionPolicy === ExtensionsPolicy.allowMicrosoft) {
|
||||
if (extension.publisherDisplayName === 'Microsoft') {
|
||||
await this.downloadOrBrowse(extension).then(() => this.checkAndEnableDisabledDependencies(gallery.identifier));
|
||||
@@ -916,7 +920,8 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
return Promise.reject(new Error(nls.localize('incompatible', "Unable to install extension '{0}' with version '{1}' as it is not compatible with Azure Data Studio.", extension.gallery!.identifier.id, version)));
|
||||
}
|
||||
return this.installWithProgress(async () => {
|
||||
await this.extensionService.installFromGallery(gallery);
|
||||
const extensionService = extension.server && extension.local && !isLanguagePackExtension(extension.local.manifest) ? extension.server.extensionManagementService : this.extensionService;
|
||||
await extensionService.installFromGallery(gallery);
|
||||
if (extension.latestVersion !== version) {
|
||||
this.ignoreAutoUpdate(new ExtensionIdentifierWithVersion(gallery.identifier, version));
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { BINARY_FILE_EDITOR_ID } from 'vs/workbench/contrib/files/common/files';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
/**
|
||||
* An implementation of editor for binary files like images.
|
||||
@@ -29,7 +30,8 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor {
|
||||
@IWindowsService private readonly windowsService: IWindowsService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@ITextFileService textFileService: ITextFileService
|
||||
@ITextFileService textFileService: ITextFileService,
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
|
||||
) {
|
||||
super(
|
||||
BinaryFileEditor.ID,
|
||||
@@ -40,7 +42,8 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor {
|
||||
telemetryService,
|
||||
themeService,
|
||||
textFileService,
|
||||
storageService
|
||||
environmentService,
|
||||
storageService,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { ExplorerService } from 'vs/workbench/contrib/files/common/explorerService';
|
||||
import { SUPPORTED_ENCODINGS } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
// Viewlet Action
|
||||
export class OpenExplorerViewletAction extends ShowViewletAction {
|
||||
@@ -59,7 +60,7 @@ class FileUriLabelContribution implements IWorkbenchContribution {
|
||||
|
||||
constructor(@ILabelService labelService: ILabelService) {
|
||||
labelService.registerFormatter({
|
||||
scheme: 'file',
|
||||
scheme: Schemas.file,
|
||||
formatting: {
|
||||
label: '${authority}${path}',
|
||||
separator: sep,
|
||||
@@ -307,6 +308,7 @@ configurationRegistry.registerConfiguration({
|
||||
},
|
||||
'files.hotExit': {
|
||||
'type': 'string',
|
||||
'scope': ConfigurationScope.APPLICATION,
|
||||
'enum': [HotExitConfiguration.OFF, HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE],
|
||||
'default': HotExitConfiguration.ON_EXIT,
|
||||
'markdownEnumDescriptions': [
|
||||
|
||||
@@ -136,14 +136,15 @@ export class SaveErrorHandler extends Disposable implements ISaveErrorHandler, I
|
||||
const isReadonly = fileOperationError.fileOperationResult === FileOperationResult.FILE_READ_ONLY;
|
||||
const triedToMakeWriteable = isReadonly && fileOperationError.options && (fileOperationError.options as IWriteTextFileOptions).overwriteReadonly;
|
||||
const isPermissionDenied = fileOperationError.fileOperationResult === FileOperationResult.FILE_PERMISSION_DENIED;
|
||||
const canHandlePermissionOrReadonlyErrors = resource.scheme === Schemas.file; // https://github.com/Microsoft/vscode/issues/48659
|
||||
|
||||
// Save Elevated (cannot write elevated https://github.com/Microsoft/vscode/issues/48659)
|
||||
if (resource.scheme === Schemas.file && (isPermissionDenied || triedToMakeWriteable)) {
|
||||
// Save Elevated
|
||||
if (canHandlePermissionOrReadonlyErrors && (isPermissionDenied || triedToMakeWriteable)) {
|
||||
actions.primary!.push(this.instantiationService.createInstance(SaveElevatedAction, model, triedToMakeWriteable));
|
||||
}
|
||||
|
||||
// Overwrite (cannot overwrite readonly https://github.com/Microsoft/vscode/issues/48659)
|
||||
else if (resource.scheme === Schemas.file && isReadonly) {
|
||||
// Overwrite
|
||||
else if (canHandlePermissionOrReadonlyErrors && isReadonly) {
|
||||
actions.primary!.push(this.instantiationService.createInstance(OverwriteReadonlyAction, model));
|
||||
}
|
||||
|
||||
@@ -158,13 +159,14 @@ export class SaveErrorHandler extends Disposable implements ISaveErrorHandler, I
|
||||
// Discard
|
||||
actions.primary!.push(this.instantiationService.createInstance(ExecuteCommandAction, REVERT_FILE_COMMAND_ID, nls.localize('discard', "Discard")));
|
||||
|
||||
if (isReadonly) {
|
||||
// Message
|
||||
if (canHandlePermissionOrReadonlyErrors && isReadonly) {
|
||||
if (triedToMakeWriteable) {
|
||||
message = isWindows ? nls.localize('readonlySaveErrorAdmin', "Failed to save '{0}': File is read-only. Select 'Overwrite as Admin' to retry as administrator.", basename(resource)) : nls.localize('readonlySaveErrorSudo', "Failed to save '{0}': File is read-only. Select 'Overwrite as Sudo' to retry as superuser.", basename(resource));
|
||||
} else {
|
||||
message = nls.localize('readonlySaveError', "Failed to save '{0}': File is read-only. Select 'Overwrite' to attempt to make it writeable.", basename(resource));
|
||||
}
|
||||
} else if (isPermissionDenied) {
|
||||
} else if (canHandlePermissionOrReadonlyErrors && isPermissionDenied) {
|
||||
message = isWindows ? nls.localize('permissionDeniedSaveError', "Failed to save '{0}': Insufficient permissions. Select 'Retry as Admin' to retry as administrator.", basename(resource)) : nls.localize('permissionDeniedSaveErrorSudo', "Failed to save '{0}': Insufficient permissions. Select 'Retry as Sudo' to retry as superuser.", basename(resource));
|
||||
} else {
|
||||
message = nls.localize('genericSaveError', "Failed to save '{0}': {1}", basename(resource), toErrorMessage(error, false));
|
||||
@@ -246,7 +248,7 @@ class ResolveSaveConflictAction extends Action {
|
||||
|
||||
return this.editorService.openEditor(
|
||||
{
|
||||
leftResource: URI.from({ scheme: CONFLICT_RESOLUTION_SCHEME, path: resource.fsPath }),
|
||||
leftResource: resource.with({ scheme: CONFLICT_RESOLUTION_SCHEME }),
|
||||
rightResource: resource,
|
||||
label: editorLabel,
|
||||
options: { pinned: true }
|
||||
|
||||
@@ -50,7 +50,7 @@ registerEditorAction(class FormatDocumentMultipleAction extends EditorAction {
|
||||
return commandService.executeCommand('editor.action.formatDocument');
|
||||
} else {
|
||||
const langName = model.getLanguageIdentifier().language;
|
||||
const message = nls.localize('no.rovider', "There is no formatter for '{0}'-files installed.", langName);
|
||||
const message = nls.localize('no.provider', "There is no formatter for '{0}'-files installed.", langName);
|
||||
const choice = {
|
||||
label: nls.localize('install.formatter', "Install Formatter..."),
|
||||
run: () => showExtensionQuery(viewletService, `category:formatters ${langName}`)
|
||||
|
||||
@@ -159,6 +159,11 @@ export const tocData: ITOCEntry = {
|
||||
id: 'features/comments',
|
||||
label: localize('comments', "Comments"),
|
||||
settings: ['comments.*']
|
||||
},
|
||||
{
|
||||
id: 'features/remote',
|
||||
label: localize('remote', "Remote"),
|
||||
settings: ['remote.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -418,14 +418,14 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
|
||||
.then(() => {
|
||||
const remoteAuthority = environmentService.configuration.remoteAuthority;
|
||||
const hostLabel = labelService.getHostLabel(REMOTE_HOST_SCHEME, remoteAuthority) || remoteAuthority;
|
||||
const label = nls.localize('openRemoteSettings', "Open User Settings ({0})", hostLabel);
|
||||
const label = nls.localize('openRemoteSettings', "Open Remote Settings ({0})", hostLabel);
|
||||
CommandsRegistry.registerCommand(OpenRemoteSettingsAction.ID, serviceAccessor => {
|
||||
serviceAccessor.get(IInstantiationService).createInstance(OpenRemoteSettingsAction, OpenRemoteSettingsAction.ID, label).run();
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: OpenRemoteSettingsAction.ID,
|
||||
title: { value: label, original: `Preferences: Open User Settings (${hostLabel})` },
|
||||
title: { value: label, original: `Preferences: Open Remote Settings (${hostLabel})` },
|
||||
category: nls.localize('preferencesCategory', "Preferences")
|
||||
},
|
||||
when: RemoteAuthorityContext.notEqualsTo('')
|
||||
|
||||
@@ -205,7 +205,7 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
this.updateStyles();
|
||||
}
|
||||
|
||||
setInput(input: SettingsEditor2Input, options: SettingsEditorOptions, token: CancellationToken): Promise<void> {
|
||||
setInput(input: SettingsEditor2Input, options: SettingsEditorOptions | null, token: CancellationToken): Promise<void> {
|
||||
this.inSettingsEditorContextKey.set(true);
|
||||
return super.setInput(input, options, token)
|
||||
.then(() => new Promise(process.nextTick)) // Force setInput to be async
|
||||
@@ -213,10 +213,10 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
return this.render(token);
|
||||
})
|
||||
.then(() => {
|
||||
options = options || SettingsEditorOptions.create({});
|
||||
|
||||
if (!this.viewState.settingsTarget) {
|
||||
if (!options) {
|
||||
options = SettingsEditorOptions.create({ target: ConfigurationTarget.USER_LOCAL });
|
||||
} else if (!options.target) {
|
||||
if (!options.target) {
|
||||
options.target = ConfigurationTarget.USER_LOCAL;
|
||||
}
|
||||
}
|
||||
@@ -1065,7 +1065,7 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
this.searchInProgress = null;
|
||||
}
|
||||
|
||||
this.viewState.filterToCategory = undefined;
|
||||
this.tocTree.setFocus([]);
|
||||
this.tocTreeModel.currentSearchModel = this.searchResultModel;
|
||||
this.onSearchModeToggled();
|
||||
|
||||
@@ -1206,8 +1206,7 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
this.tocTreeModel.update();
|
||||
}
|
||||
|
||||
this.tocTree.setSelection([]);
|
||||
this.viewState.filterToCategory = undefined;
|
||||
this.tocTree.setFocus([]);
|
||||
this.tocTree.expandAll();
|
||||
|
||||
this.renderTree(undefined, true);
|
||||
|
||||
@@ -26,12 +26,12 @@ const id = 'workbench.action.openSnippets';
|
||||
|
||||
namespace ISnippetPick {
|
||||
export function is(thing: object): thing is ISnippetPick {
|
||||
return thing && typeof (<ISnippetPick>thing).filepath === 'string';
|
||||
return thing && URI.isUri((<ISnippetPick>thing).filepath);
|
||||
}
|
||||
}
|
||||
|
||||
interface ISnippetPick extends IQuickPickItem {
|
||||
filepath: string;
|
||||
filepath: URI;
|
||||
hint?: true;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ async function computePicks(snippetService: ISnippetsService, envService: IEnvir
|
||||
|
||||
existing.push({
|
||||
label: basename(file.location.fsPath),
|
||||
filepath: file.location.fsPath,
|
||||
filepath: file.location,
|
||||
description: names.size === 0
|
||||
? nls.localize('global.scope', "(global)")
|
||||
: nls.localize('global.1', "({0})", values(names).join(', '))
|
||||
@@ -83,7 +83,7 @@ async function computePicks(snippetService: ISnippetsService, envService: IEnvir
|
||||
existing.push({
|
||||
label: basename(file.location.fsPath),
|
||||
description: `(${modeService.getLanguageName(mode)})`,
|
||||
filepath: file.location.fsPath
|
||||
filepath: file.location
|
||||
});
|
||||
seen.add(mode);
|
||||
}
|
||||
@@ -96,15 +96,15 @@ async function computePicks(snippetService: ISnippetsService, envService: IEnvir
|
||||
future.push({
|
||||
label: mode,
|
||||
description: `(${label})`,
|
||||
filepath: join(dir, `${mode}.json`),
|
||||
filepath: URI.file(join(dir, `${mode}.json`)),
|
||||
hint: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
existing.sort((a, b) => {
|
||||
let a_ext = extname(a.filepath);
|
||||
let b_ext = extname(b.filepath);
|
||||
let a_ext = extname(a.filepath.path);
|
||||
let b_ext = extname(b.filepath.path);
|
||||
if (a_ext === b_ext) {
|
||||
return a.label.localeCompare(b.label);
|
||||
} else if (a_ext === '.code-snippets') {
|
||||
@@ -165,7 +165,7 @@ async function createSnippetFile(scope: string, defaultPath: URI, windowService:
|
||||
}
|
||||
|
||||
async function createLanguageSnippetFile(pick: ISnippetPick, fileService: IFileService, textFileService: ITextFileService) {
|
||||
if (await fileService.exists(URI.file(pick.filepath))) {
|
||||
if (await fileService.exists(pick.filepath)) {
|
||||
return;
|
||||
}
|
||||
const contents = [
|
||||
@@ -185,7 +185,7 @@ async function createLanguageSnippetFile(pick: ISnippetPick, fileService: IFileS
|
||||
'\t// }',
|
||||
'}'
|
||||
].join('\n');
|
||||
await textFileService.write(URI.file(pick.filepath), contents);
|
||||
await textFileService.write(pick.filepath, contents);
|
||||
}
|
||||
|
||||
CommandsRegistry.registerCommand(id, async (accessor): Promise<any> => {
|
||||
@@ -240,7 +240,7 @@ CommandsRegistry.registerCommand(id, async (accessor): Promise<any> => {
|
||||
if (pick.hint) {
|
||||
await createLanguageSnippetFile(pick, fileService, textFileService);
|
||||
}
|
||||
return opener.open(URI.file(pick.filepath));
|
||||
return opener.open(pick.filepath);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -246,8 +246,7 @@ export class WorkspaceStats implements IWorkbenchContribution {
|
||||
|
||||
/* __GDPR__FRAGMENT__
|
||||
"WorkspaceTags" : {
|
||||
"workbench.filesToOpen" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbench.filesToCreate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbench.filesToOpenOrCreate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbench.filesToDiff" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspace.id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"workspace.roots" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
@@ -352,9 +351,8 @@ export class WorkspaceStats implements IWorkbenchContribution {
|
||||
|
||||
tags['workspace.id'] = workspaceId;
|
||||
|
||||
const { filesToOpen, filesToCreate, filesToDiff } = configuration;
|
||||
tags['workbench.filesToOpen'] = filesToOpen && filesToOpen.length || 0;
|
||||
tags['workbench.filesToCreate'] = filesToCreate && filesToCreate.length || 0;
|
||||
const { filesToOpenOrCreate, filesToDiff } = configuration;
|
||||
tags['workbench.filesToOpenOrCreate'] = filesToOpenOrCreate && filesToOpenOrCreate.length || 0;
|
||||
tags['workbench.filesToDiff'] = filesToDiff && filesToDiff.length || 0;
|
||||
|
||||
const isEmpty = state === WorkbenchState.EMPTY;
|
||||
@@ -586,11 +584,9 @@ export class WorkspaceStats implements IWorkbenchContribution {
|
||||
return folder && [folder];
|
||||
}
|
||||
|
||||
private findFolder({ filesToOpen, filesToCreate, filesToDiff }: IWindowConfiguration): URI | undefined {
|
||||
if (filesToOpen && filesToOpen.length) {
|
||||
return this.parentURI(filesToOpen[0].fileUri);
|
||||
} else if (filesToCreate && filesToCreate.length) {
|
||||
return this.parentURI(filesToCreate[0].fileUri);
|
||||
private findFolder({ filesToOpenOrCreate, filesToDiff }: IWindowConfiguration): URI | undefined {
|
||||
if (filesToOpenOrCreate && filesToOpenOrCreate.length) {
|
||||
return this.parentURI(filesToOpenOrCreate[0].fileUri);
|
||||
} else if (filesToDiff && filesToDiff.length) {
|
||||
return this.parentURI(filesToDiff[0].fileUri);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr
|
||||
) {
|
||||
super();
|
||||
|
||||
const { filesToOpen, filesToCreate, filesToDiff } = environmentService.configuration;
|
||||
const { filesToOpenOrCreate, filesToDiff } = environmentService.configuration;
|
||||
const activeViewlet = viewletService.getActiveViewlet();
|
||||
|
||||
/* __GDPR__
|
||||
@@ -47,8 +47,7 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr
|
||||
"windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbench.filesToOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbench.filesToCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbench.filesToOpenOrCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
@@ -64,8 +63,7 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr
|
||||
userAgent: navigator.userAgent,
|
||||
windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth },
|
||||
emptyWorkbench: contextService.getWorkbenchState() === WorkbenchState.EMPTY,
|
||||
'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0,
|
||||
'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0,
|
||||
'workbench.filesToOpenOrCreate': filesToOpenOrCreate && filesToOpenOrCreate.length || 0,
|
||||
'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0,
|
||||
customKeybindingsCount: keybindingsService.customKeybindingsCount(),
|
||||
theme: themeService.getColorTheme().id,
|
||||
|
||||
@@ -339,7 +339,7 @@ export class CreateNewTerminalAction extends Action {
|
||||
// Don't create the instance if the workspace picker was canceled
|
||||
return null;
|
||||
}
|
||||
return this.terminalService.createTerminal({ cwd: workspace.uri.fsPath }, true);
|
||||
return this.terminalService.createTerminal({ cwd: workspace.uri }, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
@@ -131,7 +131,7 @@ export class TerminalProcessManager implements ITerminalProcessManager {
|
||||
});
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(hasRemoteAuthority ? REMOTE_HOST_SCHEME : undefined);
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
|
||||
this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, this._configHelper);
|
||||
} else {
|
||||
this._process = this._launchProcess(shellLaunchConfig, cols, rows);
|
||||
|
||||
@@ -34,24 +34,26 @@ export function registerFileProtocol(
|
||||
getRoots: () => ReadonlyArray<URI>
|
||||
) {
|
||||
contents.session.protocol.registerBufferProtocol(protocol, (request, callback: any) => {
|
||||
if (extensionLocation && extensionLocation.scheme === REMOTE_HOST_SCHEME) {
|
||||
const requestUri = URI.parse(request.url);
|
||||
const redirectedUri = URI.from({
|
||||
scheme: REMOTE_HOST_SCHEME,
|
||||
authority: extensionLocation.authority,
|
||||
path: '/vscode-resource',
|
||||
query: JSON.stringify({
|
||||
requestResourcePath: requestUri.path
|
||||
})
|
||||
});
|
||||
resolveContent(textFileService, redirectedUri, getMimeType(requestUri), callback);
|
||||
return;
|
||||
}
|
||||
|
||||
const requestPath = URI.parse(request.url).path;
|
||||
const normalizedPath = URI.file(requestPath);
|
||||
for (const root of getRoots()) {
|
||||
if (startsWith(normalizedPath.fsPath, root.fsPath + sep)) {
|
||||
if (!startsWith(normalizedPath.fsPath, root.fsPath + sep)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (extensionLocation && extensionLocation.scheme === REMOTE_HOST_SCHEME) {
|
||||
const requestUri = URI.parse(request.url);
|
||||
const redirectedUri = URI.from({
|
||||
scheme: REMOTE_HOST_SCHEME,
|
||||
authority: extensionLocation.authority,
|
||||
path: '/vscode-resource',
|
||||
query: JSON.stringify({
|
||||
requestResourcePath: requestUri.path
|
||||
})
|
||||
});
|
||||
resolveContent(textFileService, redirectedUri, getMimeType(requestUri), callback);
|
||||
return;
|
||||
} else {
|
||||
resolveContent(textFileService, normalizedPath, getMimeType(normalizedPath), callback);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user