From cb5558b99d633fb775b2ac0e56f7b7304ce3cff9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 15 Aug 2018 14:41:10 -0700 Subject: [PATCH] Fix #50641 - handle different settings scopes correctly in UI --- .../preferences/browser/preferencesActions.ts | 39 ++++----- .../preferences/browser/preferencesEditor.ts | 8 +- .../preferences/browser/settingsEditor2.ts | 32 ++++--- .../common/preferencesContribution.ts | 6 +- .../preferences.contribution.ts | 12 ++- .../preferences/browser/preferencesService.ts | 83 ++++++++++++++++--- .../preferences/common/preferences.ts | 11 ++- .../common/preferencesEditorInput.ts | 23 ++--- 8 files changed, 135 insertions(+), 79 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts index 60ec2e5e99d..e14be3af87a 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts @@ -45,13 +45,13 @@ export class OpenSettings2Action extends Action { constructor( id: string, label: string, - @IPreferencesService private preferencesService2: IPreferencesService + @IPreferencesService private preferencesService: IPreferencesService ) { super(id, label); } public run(event?: any): TPromise { - return this.preferencesService2.openSettings2(); + return this.preferencesService.openSettings(false); } } @@ -71,9 +71,8 @@ export class OpenSettingsAction extends Action { } public run(event?: any): TPromise { - return this.configurationService.getValue('workbench.settings.editor') === 'json' ? - this.preferencesService.openSettings() : - this.preferencesService.openSettings2(); + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openSettings(jsonEditorPreferred); } } @@ -110,9 +109,8 @@ export class OpenGlobalSettingsAction extends Action { } public run(event?: any): TPromise { - return this.configurationService.getValue('workbench.settings.editor') === 'json' ? - this.preferencesService.openGlobalSettings() : - this.preferencesService.openSettings2(); + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openGlobalSettings(jsonEditorPreferred); } } @@ -194,9 +192,8 @@ export class OpenWorkspaceSettingsAction extends Action { } public run(event?: any): TPromise { - return this.configurationService.getValue('workbench.settings.editor') === 'json' ? - this.preferencesService.openWorkspaceSettings() : - this.preferencesService.openSettings2(); + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openWorkspaceSettings(jsonEditorPreferred); } public dispose(): void { @@ -234,17 +231,15 @@ export class OpenFolderSettingsAction extends Action { } public run(): TPromise { - if (this.configurationService.getValue('workbench.settings.editor') === 'json') { - return this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID) - .then(workspaceFolder => { - if (workspaceFolder) { - return this.commandService.executeCommand(OPEN_FOLDER_SETTINGS_COMMAND, workspaceFolder.uri); - } - return null; - }); - } else { - return this.preferencesService.openSettings2(); - } + return this.commandService.executeCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID) + .then(workspaceFolder => { + if (workspaceFolder) { + const jsonEditorPreferred = this.configurationService.getValue('workbench.settings.editor') === 'json'; + return this.preferencesService.openFolderSettings(workspaceFolder.uri, jsonEditorPreferred); + } + + return null; + }); } public dispose(): void { diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index 3f1ba5f6ebd..a05b30b32be 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -120,7 +120,7 @@ export class PreferencesEditor extends BaseEditor { }); openSettings2Button.label = nls.localize('openSettings2Label', "new settings editor"); openSettings2Button.element.classList.add('open-settings2-button'); - this._register(openSettings2Button.onDidClick(() => this.preferencesService.openSettings2())); + this._register(openSettings2Button.onDidClick(() => this.preferencesService.openSettings(false))); this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, this.headerContainer, { ariaLabel: nls.localize('SearchSettingsWidget.AriaLabel', "Search settings"), @@ -263,11 +263,11 @@ export class PreferencesEditor extends BaseEditor { const promise = this.input && this.input.isDirty() ? this.input.save() : TPromise.as(true); promise.done(value => { if (target === ConfigurationTarget.USER) { - this.preferencesService.switchSettings(ConfigurationTarget.USER, this.preferencesService.userSettingsResource); + this.preferencesService.switchSettings(ConfigurationTarget.USER, this.preferencesService.userSettingsResource, true); } else if (target === ConfigurationTarget.WORKSPACE) { - this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE, this.preferencesService.workspaceSettingsResource); + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE, this.preferencesService.workspaceSettingsResource, true); } else if (target instanceof URI) { - this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE_FOLDER, target); + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE_FOLDER, target, true); } }); } diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 31e0b9e6e33..d715380fc68 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -43,6 +43,7 @@ import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsSer import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; const $ = DOM.$; @@ -228,12 +229,15 @@ export class SettingsEditor2 extends BaseEditor { const targetWidgetContainer = DOM.append(headerControlsContainer, $('.settings-target-container')); this.settingsTargetsWidget = this._register(this.instantiationService.createInstance(SettingsTargetsWidget, targetWidgetContainer)); this.settingsTargetsWidget.settingsTarget = ConfigurationTarget.USER; - this.settingsTargetsWidget.onDidTargetChange(() => { - this.viewState.settingsTarget = this.settingsTargetsWidget.settingsTarget; - this.toolbar.context = { target: this.settingsTargetsWidget.settingsTarget }; - - this.settingsTreeModel.update(); - this.renderTree(); + this.settingsTargetsWidget.onDidTargetChange(target => { + this.viewState.settingsTarget = target; + if (target === ConfigurationTarget.USER) { + this.preferencesService.openGlobalSettings(); + } else if (target === ConfigurationTarget.WORKSPACE) { + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE, this.preferencesService.workspaceSettingsResource); + } else if (target instanceof URI) { + this.preferencesService.switchSettings(ConfigurationTarget.WORKSPACE_FOLDER, target); + } }); this.createHeaderControls(headerControlsContainer); @@ -480,7 +484,7 @@ export class SettingsEditor2 extends BaseEditor { // Force a render afterwards because onDidConfigurationUpdate doesn't fire if the update doesn't result in an effective setting value change const settingsTarget = this.settingsTargetsWidget.settingsTarget; const resource = URI.isUri(settingsTarget) ? settingsTarget : undefined; - const configurationTarget = (resource ? undefined : settingsTarget); + const configurationTarget = (resource ? ConfigurationTarget.WORKSPACE_FOLDER : settingsTarget); const overrides: IConfigurationOverrides = { resource }; // If the user is changing the value back to the default, do a 'reset' instead @@ -567,13 +571,15 @@ export class SettingsEditor2 extends BaseEditor { private render(token: CancellationToken): TPromise { if (this.input) { return this.input.resolve() - .then((model: DefaultSettingsEditorModel) => { + .then(model => { if (token.isCancellationRequested) { return void 0; } - this._register(model.onDidChangeGroups(() => this.onConfigUpdate())); - this.defaultSettingsEditorModel = model; + return this.preferencesService.createPreferencesEditorModel((model).textEditorModel.uri); + }).then((defaultSettingsEditorModel: DefaultSettingsEditorModel) => { + this._register(defaultSettingsEditorModel.onDidChangeGroups(() => this.onConfigUpdate())); + this.defaultSettingsEditorModel = defaultSettingsEditorModel; return this.onConfigUpdate(); }); } @@ -945,11 +951,11 @@ class OpenSettingsAction extends Action { private _run(context?: ISettingsToolbarContext): TPromise { const target = context && context.target; if (target === ConfigurationTarget.USER) { - return this.preferencesService.openGlobalSettings(); + return this.preferencesService.openGlobalSettings(true); } else if (target === ConfigurationTarget.WORKSPACE) { - return this.preferencesService.openWorkspaceSettings(); + return this.preferencesService.openWorkspaceSettings(true); } else if (URI.isUri(target)) { - return this.preferencesService.openFolderSettings(target); + return this.preferencesService.openFolderSettings(target, true); } return TPromise.wrap(null); diff --git a/src/vs/workbench/parts/preferences/common/preferencesContribution.ts b/src/vs/workbench/parts/preferences/common/preferencesContribution.ts index f1c464e54c5..14494b0bdb3 100644 --- a/src/vs/workbench/parts/preferences/common/preferencesContribution.ts +++ b/src/vs/workbench/parts/preferences/common/preferencesContribution.ts @@ -82,7 +82,7 @@ export class PreferencesContribution implements IWorkbenchContribution { // Global User Settings File if (isEqual(resource, URI.file(this.environmentService.appSettingsPath), !isLinux)) { - return { override: this.preferencesService.openGlobalSettings(options, group) }; + return { override: this.preferencesService.openGlobalSettings(true, options, group) }; } // Single Folder Workspace Settings File @@ -90,7 +90,7 @@ export class PreferencesContribution implements IWorkbenchContribution { if (state === WorkbenchState.FOLDER) { const folders = this.workspaceService.getWorkspace().folders; if (isEqual(resource, folders[0].toResource(FOLDER_SETTINGS_PATH), hasToIgnoreCase(resource))) { - return { override: this.preferencesService.openWorkspaceSettings(options, group) }; + return { override: this.preferencesService.openWorkspaceSettings(true, options, group) }; } } @@ -99,7 +99,7 @@ export class PreferencesContribution implements IWorkbenchContribution { const folders = this.workspaceService.getWorkspace().folders; for (let i = 0; i < folders.length; i++) { if (isEqual(resource, folders[i].toResource(FOLDER_SETTINGS_PATH), hasToIgnoreCase(resource))) { - return { override: this.preferencesService.openFolderSettings(folders[i].uri, options, group) }; + return { override: this.preferencesService.openFolderSettings(folders[i].uri, true, options, group) }; } } } diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index 37c60e73f60..f12c7b9c456 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -152,11 +152,17 @@ class KeybindingsEditorInputFactory implements IEditorInputFactory { class SettingsEditor2InputFactory implements IEditorInputFactory { public serialize(editorInput: SettingsEditor2Input): string { - return JSON.stringify({}); + const input = editorInput; + + const serialized: ISerializedDefaultPreferencesEditorInput = { resource: input.getResource().toString() }; + + return JSON.stringify(serialized); } - public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput { - return instantiationService.createInstance(SettingsEditor2Input); + public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): SettingsEditor2Input { + const deserialized: ISerializedDefaultPreferencesEditorInput = JSON.parse(serializedEditorInput); + + return instantiationService.createInstance(SettingsEditor2Input, URI.parse(deserialized.resource)); } } diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 8954289dfeb..c7d519cf89f 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -45,6 +45,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic _serviceBrand: any; private lastOpenedSettingsInput: PreferencesEditorInput = null; + private lastOpenedSettings2Input: SettingsEditor2Input = null; private readonly _onDispose: Emitter = new Emitter(); @@ -176,34 +177,52 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.editorService.openEditor({ resource: this.userSettingsResource }); } - openSettings(): TPromise { + openSettings(jsonEditor?: boolean): TPromise { + if (!jsonEditor) { + return this.openSettings2(); + } + const editorInput = this.getActiveSettingsEditorInput() || this.lastOpenedSettingsInput; const resource = editorInput ? editorInput.master.getResource() : this.userSettingsResource; const target = this.getConfigurationTargetFromSettingsResource(resource); return this.openOrSwitchSettings(target, resource); } - openGlobalSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise { - return this.openOrSwitchSettings(ConfigurationTarget.USER, this.userSettingsResource, options, group); + private openSettings2(): TPromise { + const editorInput = this.getActiveSettingsEditor2Input() || this.lastOpenedSettings2Input; + const resource = editorInput ? editorInput.getResource() : this.userSettingsResource; + const target = this.getConfigurationTargetFromSettingsResource(resource); + return this.openOrSwitchSettings2(target); } - openSettings2(): TPromise { - return this.editorService.openEditor(this.instantiationService.createInstance(SettingsEditor2Input), { pinned: true }).then(() => null); + openGlobalSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise { + return jsonEditor ? + this.openOrSwitchSettings(ConfigurationTarget.USER, this.userSettingsResource, options, group) : + this.openOrSwitchSettings2(ConfigurationTarget.USER, options, group); } - openWorkspaceSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise { + openWorkspaceSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise { if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { this.notificationService.info(nls.localize('openFolderFirst', "Open a folder first to create workspace settings")); return TPromise.as(null); } - return this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE, this.workspaceSettingsResource, options, group); + + return jsonEditor ? + this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE, this.workspaceSettingsResource, options, group) : + this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE, options, group); } - openFolderSettings(folder: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise { - return this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE_FOLDER, this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder), options, group); + openFolderSettings(folder: URI, jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise { + return jsonEditor ? + this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE_FOLDER, this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder), options, group) : + this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE_FOLDER, options, group); } - switchSettings(target: ConfigurationTarget, resource: URI): TPromise { + switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): TPromise { + if (!jsonEditor) { + return this.switchSettings2(target); + } + const activeControl = this.editorService.activeControl; if (activeControl && activeControl.input instanceof PreferencesEditorInput) { return this.doSwitchSettings(target, resource, activeControl.input, activeControl.group).then(() => null); @@ -212,6 +231,16 @@ export class PreferencesService extends Disposable implements IPreferencesServic } } + switchSettings2(target: ConfigurationTarget): TPromise { + const activeControl = this.editorService.activeControl; + const resource = this.getDefaultSettingsResource(target); + if (activeControl && activeControl.input instanceof SettingsEditor2Input) { + return this.doSwitchSettings2(resource, activeControl.input, activeControl.group).then(() => null); + } else { + return this.doOpenSettings2(resource).then(() => null); + } + } + openGlobalKeybindingSettings(textual: boolean): TPromise { /* __GDPR__ "openKeybindings" : { @@ -271,6 +300,16 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.doOpenSettings(configurationTarget, resource, options, group); } + private openOrSwitchSettings2(configurationTarget: ConfigurationTarget, options?: IEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): TPromise { + const editorInput = this.getActiveSettingsEditor2Input(group); + const resource = this.getDefaultSettingsResource(configurationTarget); + if (editorInput && editorInput.getResource().fsPath !== resource.fsPath) { + return this.doSwitchSettings2(resource, editorInput, group); + } + + return this.doOpenSettings2(resource, options, group); + } + private doOpenSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise { const openDefaultSettings = !!this.configurationService.getValue(DEFAULT_SETTINGS_EDITOR_SETTING); return this.getOrCreateEditableSettingsEditorInput(configurationTarget, resource) @@ -291,6 +330,12 @@ export class PreferencesService extends Disposable implements IPreferencesServic }); } + private doOpenSettings2(resource: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise { + const settingsEditorInput = this.instantiationService.createInstance(SettingsEditor2Input, resource); + this.lastOpenedSettings2Input = settingsEditorInput; + return this.editorService.openEditor(settingsEditorInput, options, group); + } + private doSwitchSettings(target: ConfigurationTarget, resource: URI, input: PreferencesEditorInput, group: IEditorGroup): TPromise { return this.getOrCreateEditableSettingsEditorInput(target, this.getEditableSettingsURI(target, resource)) .then(toInput => { @@ -308,10 +353,28 @@ export class PreferencesService extends Disposable implements IPreferencesServic }); } + private doSwitchSettings2(resource: URI, input: SettingsEditor2Input, group: IEditorGroup): TPromise { + return group.openEditor(input).then(() => { + const replaceWith = this.instantiationService.createInstance(SettingsEditor2Input, resource); + + return group.replaceEditors([{ + editor: input, + replacement: replaceWith + }]).then(() => { + this.lastOpenedSettings2Input = replaceWith; + return group.activeControl; + }); + }); + } + private getActiveSettingsEditorInput(group: IEditorGroup = this.editorGroupService.activeGroup): PreferencesEditorInput { return group.editors.filter(e => e instanceof PreferencesEditorInput)[0]; } + private getActiveSettingsEditor2Input(group: IEditorGroup = this.editorGroupService.activeGroup): SettingsEditor2Input { + return group.editors.filter(e => e instanceof SettingsEditor2Input)[0]; + } + private getConfigurationTargetFromSettingsResource(resource: URI): ConfigurationTarget { if (this.userSettingsResource.toString() === resource.toString()) { return ConfigurationTarget.USER; diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 6e8cd0cd871..db2511babc9 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -152,12 +152,11 @@ export interface IPreferencesService { createPreferencesEditorModel(uri: URI): TPromise>; openRawDefaultSettings(): TPromise; - openSettings(): TPromise; - openSettings2(): TPromise; - openGlobalSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise; - openWorkspaceSettings(options?: IEditorOptions, group?: IEditorGroup): TPromise; - openFolderSettings(folder: URI, options?: IEditorOptions, group?: IEditorGroup): TPromise; - switchSettings(target: ConfigurationTarget, resource: URI): TPromise; + openSettings(jsonEditor?: boolean): TPromise; + openGlobalSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise; + openWorkspaceSettings(jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise; + openFolderSettings(folder: URI, jsonEditor?: boolean, options?: IEditorOptions, group?: IEditorGroup): TPromise; + switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): TPromise; openGlobalKeybindingSettings(textual: boolean): TPromise; openDefaultKeybindingsFile(): TPromise; diff --git a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts index 045707197af..19bf4306846 100644 --- a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts +++ b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts @@ -13,8 +13,6 @@ import { EditorInput, SideBySideEditorInput, Verbosity } from 'vs/workbench/comm import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { KeybindingsEditorModel } from 'vs/workbench/services/preferences/common/keybindingsEditorModel'; -import { IPreferencesService } from './preferences'; -import { DefaultSettingsEditorModel } from './preferencesModels'; export class PreferencesEditorInput extends SideBySideEditorInput { public static readonly ID: string = 'workbench.editorinputs.preferencesEditorInput'; @@ -79,29 +77,18 @@ export class KeybindingsEditorInput extends EditorInput { } } -export class SettingsEditor2Input extends EditorInput { +export class SettingsEditor2Input extends ResourceEditorInput { public static readonly ID: string = 'workbench.input.settings2'; - constructor( - @IPreferencesService private preferencesService: IPreferencesService + constructor(defaultSettingsResource: URI, + @ITextModelService textModelResolverService: ITextModelService, + @IHashService hashService: IHashService ) { - super(); + super(nls.localize('settingsEditor2InputName', "Settings (Preview)"), '', defaultSettingsResource, textModelResolverService, hashService); } getTypeId(): string { return SettingsEditor2Input.ID; } - - getName(): string { - return nls.localize('settingsEditor2InputName', "Settings (Preview)"); - } - - resolve(): TPromise { - return >this.preferencesService.createPreferencesEditorModel(URI.parse('vscode://defaultsettings/0/settings.json')); - } - - matches(otherInput: any): boolean { - return otherInput instanceof SettingsEditor2Input; - } } -- GitLab