From b8863884aa27517359b1b9acbe7d05b7ed51c251 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 29 Nov 2016 17:51:56 +0100 Subject: [PATCH] Push changes - Separate header widget from the editor - Create Default preferences models always --- .../common/contentprovider.contribution.ts | 9 +- .../preferences/browser/media/preferences.css | 117 ++++---- .../browser/preferences.contribution.ts | 11 +- .../preferences/browser/preferencesEditor.ts | 270 +++++++++++++----- .../preferences/browser/preferencesService.ts | 108 +++---- .../preferences/browser/preferencesWidgets.ts | 113 ++------ .../parts/preferences/common/preferences.ts | 9 +- .../preferences/common/preferencesModels.ts | 9 +- 8 files changed, 326 insertions(+), 320 deletions(-) diff --git a/src/vs/workbench/parts/contentprovider/common/contentprovider.contribution.ts b/src/vs/workbench/parts/contentprovider/common/contentprovider.contribution.ts index a74158b8977..d82c95436f2 100644 --- a/src/vs/workbench/parts/contentprovider/common/contentprovider.contribution.ts +++ b/src/vs/workbench/parts/contentprovider/common/contentprovider.contribution.ts @@ -47,14 +47,7 @@ export class WorkbenchContentProvider implements IWorkbenchContribution { return TPromise.as(this.modelService.createModel(modelContent, mode, uri)); } } - return this.preferencesService.resolvePreferencesEditorModel(uri) - .then(preferencesModel => { - if (preferencesModel) { - let mode = this.modeService.getOrCreateMode('json'); - return TPromise.as(this.modelService.createModel(preferencesModel.content, mode, uri)); - } - return null; - }); + return null; } }); } diff --git a/src/vs/workbench/parts/preferences/browser/media/preferences.css b/src/vs/workbench/parts/preferences/browser/media/preferences.css index 7461e46437f..5e44b6dbc5f 100644 --- a/src/vs/workbench/parts/preferences/browser/media/preferences.css +++ b/src/vs/workbench/parts/preferences/browser/media/preferences.css @@ -3,6 +3,54 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +.settings-header-widget { + display: none; + border-bottom: 1px solid #efefef; +} +.settings-header-widget.show { + display: flex; +} + +.vs-dark .settings-header-widget { + border-bottom: 1px solid #2d2d2d; +} + +.settings-header-widget > .settings-header-container { + margin: 8px 0px 12px 0; +} + +.settings-header-widget > .settings-header-container > .settings-title-container { + display: flex +} + +.settings-header-widget > .settings-header-container > .settings-title-container > .settings-info-container { + color: rgba(170, 170, 170, 1); + font-style: italic; + white-space: pre-wrap; + margin-bottom: 8px; +} + +.settings-header-widget > .settings-header-container > .settings-title-container > .settings-info-container span { + padding-right: 6px; +} + +.settings-header-widget > .settings-header-container > .settings-search-container > .settings-search-input { + display: inline-block; + vertical-align: middle; +} + +.settings-header-widget > .settings-header-container > .settings-search-container > .settings-search-input > .monaco-inputbox { + height: 30px; +} + +.vs .settings-header-widget > .settings-header-container > .settings-search-container > .settings-search-input > .monaco-inputbox { + border: 1px solid #ddd; +} + +.settings-header-widget > .settings-header-container > .settings-search-container > .settings-search-input > .monaco-inputbox .input { + font-size: 14px; +} + .monaco-editor .settings-group-title-widget-container .title-container { flex: 1; width: 100%; @@ -11,8 +59,13 @@ padding-bottom: 6px; } -.monaco-editor .settings-group-title-widget-container .title-container:hover { - background-color: #CCCEDB; +.monaco-editor.vs .settings-group-title-widget-container .title-container:hover { + background-color: #e2e2e2; +} + +.monaco-editor.hc-black .settings-group-title-widget-container .title-container:hover, +.monaco-editor.vs-dark .settings-group-title-widget-container .title-container:hover { + background-color: #323232; } .monaco-editor .settings-group-title-widget-container .title-container .title { @@ -37,46 +90,6 @@ padding-left: 18px; } -.monaco-editor .settings-header-widget { - background-color: rgba(245, 245, 245, 1); - display: flex; - z-index: 11; -} - -.monaco-editor .settings-header-widget > .settings-header-container { - margin: 8px 0px 12px 0; -} - -.monaco-editor .settings-header-widget > .settings-header-container > .settings-title-container { - display: flex -} - -.monaco-editor .settings-header-widget > .settings-header-container > .settings-title-container > .settings-info-container { - color: rgba(170, 170, 170, 1); - font-style: italic; - white-space: pre-wrap; - margin-bottom: 8px; -} - -.monaco-editor .settings-header-widget > .settings-header-container > .settings-title-container > .settings-info-container span { - padding-right: 6px; -} - -.monaco-editor .settings-header-widget > .settings-header-container > .settings-search-container > .settings-search-input { - display: inline-block; - vertical-align: middle; - background-color: white; -} - -.monaco-editor .settings-header-widget > .settings-header-container > .settings-search-container > .settings-search-input > .monaco-inputbox { - height: 40px; - border: 1px solid #ddd; -} - -.monaco-editor .settings-header-widget > .settings-header-container > .settings-search-container > .settings-search-input > .monaco-inputbox .input { - font-size: large; -} - .monaco-editor .view-line:hover :not(.inline-folded).copySetting:after { cursor: pointer; content:" "; @@ -88,18 +101,8 @@ width:16px; } -.monaco-editor .copy-preferences-widget { - height: 16px; - width: 16px; - cursor: pointer; -} - -.monaco-editor.vs .copy-preferences-widget { - background: url('copy.svg') center center no-repeat; -} - -.monaco-editor.vs-dark .copy-preferences-widget, -.monaco-editor.hc-black .copy-preferences-widget { +.monaco-editor.hc-black .view-line:hover :not(.inline-folded).copySetting:after, +.monaco-editor.vs-dark .view-line:hover :not(.inline-folded).copySetting:after { background: url('copy_inverse.svg') center center no-repeat; } @@ -119,6 +122,12 @@ background: url("clear-input.svg") center center no-repeat; } +.title-actions .action-item .icon.collapseAll, .editor-actions .action-item .icon.collapseAll { background: url('collapseAll.svg') center center no-repeat; +} + +.vs-dark .title-actions .action-item .icon.collapseAll, +.vs-dark .editor-actions .action-item .icon.collapseAll { + background: url('collapseAll_inverse.svg') center center no-repeat; } \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/browser/preferences.contribution.ts index 87f92def97f..1b36cd28ea4 100644 --- a/src/vs/workbench/parts/preferences/browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/browser/preferences.contribution.ts @@ -13,7 +13,7 @@ import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; -import { DefaultPreferencesEditor, DefaultSettingsInput, DefaultKeybindingsInput } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; +import { PreferencesEditor, PreferencesEditorInput } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { OpenGlobalSettingsAction, OpenGlobalKeybindingsAction, OpenWorkspaceSettingsAction, DefineSettingAction, DefineUserSettingAction, DefineWorkspaceSettingAction } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { IPreferencesService, CONTEXT_DEFAULT_SETTINGS_EDITOR, DEFAULT_EDITOR_COMMAND_COLLAPSE_ALL } from 'vs/workbench/parts/preferences/common/preferences'; import { PreferencesService } from 'vs/workbench/parts/preferences/browser/preferencesService'; @@ -25,14 +25,13 @@ registerSingleton(IPreferencesService, PreferencesService); (Registry.as(EditorExtensions.Editors)).registerEditor( new EditorDescriptor( - DefaultPreferencesEditor.ID, - nls.localize('defaultSettingsEditor', "Default Settings Editor"), + PreferencesEditor.ID, + nls.localize('defaultPreferencesEditor', "Default Preferences Editor"), 'vs/workbench/parts/preferences/browser/preferencesEditor', - 'DefaultPreferencesEditor' + 'PreferencesEditor' ), [ - new SyncDescriptor(DefaultSettingsInput), - new SyncDescriptor(DefaultKeybindingsInput) + new SyncDescriptor(PreferencesEditorInput) ] ); diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index 6f565306a4e..647da58286d 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -6,7 +6,8 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; -import { hasClass, getDomNodePagePosition } from 'vs/base/browser/dom'; +import * as DOM from 'vs/base/browser/dom'; +import { Dimension, Builder } from 'vs/base/browser/builder'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { flatten } from 'vs/base/common/arrays'; import { IAction } from 'vs/base/common/actions'; @@ -15,127 +16,231 @@ import Event, { Emitter } from 'vs/base/common/event'; import { LinkedMap as Map } from 'vs/base/common/map'; import { Registry } from 'vs/platform/platform'; import { EditorOptions, EditorInput, } from 'vs/workbench/common/editor'; +import { IEditorModel } from 'vs/platform/editor/common/editor'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { StringEditor } from 'vs/workbench/browser/parts/editor/stringEditor'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; +import { CodeEditor } from 'vs/editor/browser/codeEditor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { - IPreferencesService, ISettingsGroup, ISetting, ISettingsEditorModel, IKeybindingsEditorModel, IPreferencesEditorModel, IFilterResult, CONTEXT_DEFAULT_SETTINGS_EDITOR, + IPreferencesService, ISettingsGroup, ISetting, IPreferencesEditorModel, IFilterResult, CONTEXT_DEFAULT_SETTINGS_EDITOR, DEFAULT_EDITOR_COMMAND_COLLAPSE_ALL } from 'vs/workbench/parts/preferences/common/preferences'; import { SettingsEditorModel, DefaultSettingsEditorModel } from 'vs/workbench/parts/preferences/common/preferencesModels'; import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions'; -import { ICodeEditor, IEditorMouseEvent } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, IEditorMouseEvent, IEditorContributionCtor } from 'vs/editor/browser/editorBrowser'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ITextModelResolverService } from 'vs/editor/common/services/resolverService'; import { DefaultSettingsHeaderWidget, SettingsGroupTitleWidget, FloatingClickWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { IContextKeyService, IContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { CommonEditorRegistry, EditorCommand } from 'vs/editor/common/editorCommonExtensions'; import { DefineUserSettingAction, DefineWorkspaceSettingAction } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing'; - - -export class DefaultPreferencesInput extends ResourceEditorInput { +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IEventService } from 'vs/platform/event/common/event'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IMessageService } from 'vs/platform/message/common/message'; +import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IThemeService } from 'vs/workbench/services/themes/common/themeService'; +import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { IModeService } from 'vs/editor/common/services/modeService'; +import { FoldingController } from 'vs/editor/contrib/folding/browser/folding'; + + +export class PreferencesEditorInput extends EditorInput { private _willDispose = new Emitter(); public willDispose: Event = this._willDispose.event; - constructor( - name: string, - description: string, - resource: URI, - @ITextModelResolverService textModelResolverService: ITextModelResolverService - ) { - super(name, description, resource, textModelResolverService); + constructor(private _defaultPreferencesResource: URI, private _isSettingsInput: boolean) { + super(); } - public getResource(): URI { - return this.resource; + get isSettings(): boolean { + return this._isSettingsInput; } - public dispose() { - this._willDispose.fire(); - this._willDispose.dispose(); - super.dispose(); + getName(): string { + return this._isSettingsInput ? nls.localize('settingsEditorName', "Default Settings") : nls.localize('keybindingsEditorName', "Default Keyboard Shortcuts"); } -} -export class DefaultSettingsInput extends DefaultPreferencesInput { - private static INSTANCE: DefaultSettingsInput; + getTypeId(): string { + return 'workbench.editorinputs.defaultpreferences'; + } - public static getInstance(instantiationService: IInstantiationService, defaultSettings: ISettingsEditorModel): DefaultSettingsInput { - if (!DefaultSettingsInput.INSTANCE) { - DefaultSettingsInput.INSTANCE = instantiationService.createInstance(DefaultSettingsInput, nls.localize('defaultName', "Default Settings"), null, defaultSettings.uri); - } - return DefaultSettingsInput.INSTANCE; + getResource(): URI { + return this._defaultPreferencesResource; } -} -export class DefaultKeybindingsInput extends DefaultPreferencesInput { - private static INSTANCE: DefaultKeybindingsInput; + supportsSplitEditor(): boolean { + return false; + } + + resolve(): TPromise { + return TPromise.wrap(null); + } - public static getInstance(instantiationService: IInstantiationService, defaultKeybindings: IKeybindingsEditorModel): DefaultKeybindingsInput { - if (!DefaultKeybindingsInput.INSTANCE) { - DefaultKeybindingsInput.INSTANCE = instantiationService.createInstance(DefaultKeybindingsInput, nls.localize('defaultKeybindings', "Default Keyboard Shortcuts"), null, defaultKeybindings.uri); + matches(other: any): boolean { + if (!(other instanceof PreferencesEditorInput)) { + return false; } + if (this._defaultPreferencesResource.fsPath !== other._defaultPreferencesResource.fsPath) { + return false; + } + return true; + } - return DefaultKeybindingsInput.INSTANCE; + dispose() { + this._willDispose.fire(); + this._willDispose.dispose(); + super.dispose(); } } -export class DefaultPreferencesEditor extends StringEditor { - - public static ID = 'workbench.editors.defaultPrefrencesEditor'; +export class PreferencesEditor extends BaseTextEditor { + public static ID: string = 'workbench.editor.defaultPreferences'; private static VIEW_STATE: Map = new Map(); private inputDisposeListener; + private defaultPreferencesEditor: CodeEditor; + private defaultSettingHeaderWidget: DefaultSettingsHeaderWidget; - public getId(): string { - return DefaultPreferencesEditor.ID; + private isFocussed = false; + private toDispose: IDisposable[] = []; + + constructor( + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IStorageService storageService: IStorageService, + @IMessageService messageService: IMessageService, + @IConfigurationService configurationService: IConfigurationService, + @IEventService eventService: IEventService, + @IWorkbenchEditorService editorService: IWorkbenchEditorService, + @IThemeService themeService: IThemeService, + @IUntitledEditorService private untitledEditorService: IUntitledEditorService, + @IPreferencesService private preferencesService: IPreferencesService, + @IInstantiationService instantiationService: IInstantiationService, + @IModelService private modelService: IModelService, + @IModeService private modeService: IModeService + ) { + super(PreferencesEditor.ID, telemetryService, instantiationService, contextService, storageService, messageService, configurationService, eventService, editorService, themeService); + } + + public createEditorControl(parent: Builder): editorCommon.IEditor { + const parentContainer = parent.getHTMLElement(); + this.defaultSettingHeaderWidget = this._register(this.instantiationService.createInstance(DefaultSettingsHeaderWidget, parentContainer)); + this._register(this.defaultSettingHeaderWidget.onDidChange(value => this.filterPreferences(value))); + this.defaultPreferencesEditor = this._register(this.instantiationService.createInstance(DefaultPreferencesEditor, parentContainer, this.getCodeEditorOptions())); + const focusTracker = this._register(DOM.trackFocus(parentContainer)); + focusTracker.addBlurListener(() => { this.isFocussed = false; }); + return this.defaultPreferencesEditor; } - protected getCodeEditorOptions(): editorCommon.IEditorOptions { + public getCodeEditorOptions(): editorCommon.IEditorOptions { const options = super.getCodeEditorOptions(); - options.lineNumbers = 'off'; - options.renderLineHighlight = 'none'; - options.scrollBeyondLastLine = false; - options.folding = false; - options.renderWhitespace = 'none'; - options.wrappingColumn = 0; + options.readOnly = true; + if (this.input && (this.input).isSettings) { + options.lineNumbers = 'off'; + options.renderLineHighlight = 'none'; + options.scrollBeyondLastLine = false; + options.folding = false; + options.renderWhitespace = 'none'; + options.wrappingColumn = 0; + } return options; } - - public setInput(input: EditorInput, options: EditorOptions): TPromise { + setInput(input: PreferencesEditorInput, options: EditorOptions): TPromise { this.listenToInput(input); - return super.setInput(input, options); + return super.setInput(input, options) + .then(() => this.createModel(input) + .then(model => this.setDefaultPreferencesEditorInput(model, input))); + } + + public layout(dimension: Dimension) { + if (this.input && (this.input).isSettings) { + const headerWidgetPosition = DOM.getDomNodePagePosition(this.defaultSettingHeaderWidget.domNode); + this.defaultPreferencesEditor.layout({ + height: dimension.height - headerWidgetPosition.height, + width: dimension.width + }); + this.defaultSettingHeaderWidget.layout(this.defaultPreferencesEditor.getLayoutInfo()); + } else { + this.defaultPreferencesEditor.layout(dimension); + } + } + + public focus(): void { + this.isFocussed = true; + if (this.input && (this.input).isSettings) { + this.defaultSettingHeaderWidget.focus(); + } else { + super.focus(); + } + } + + private createModel(input: PreferencesEditorInput): TPromise { + return this.preferencesService.createDefaultPreferencesEditorModel(input.getResource()) + .then(preferencesEditorModel => { + let mode = this.modeService.getOrCreateMode('json'); + return this.modelService.createModel(preferencesEditorModel.content, mode, preferencesEditorModel.uri); + }); + } + + private setDefaultPreferencesEditorInput(model: editorCommon.IModel, input: PreferencesEditorInput): void { + this.defaultPreferencesEditor.setModel(model); + this.defaultPreferencesEditor.updateOptions(this.getCodeEditorOptions()); + if (input.isSettings) { + this.defaultSettingHeaderWidget.show(); + this.defaultPreferencesEditor.onDidFocusEditorText(() => this.onEditorTextFocussed(), this.toDispose); + } else { + this.toDispose = dispose(this.toDispose); + this.defaultSettingHeaderWidget.hide(); + } + } + + private filterPreferences(filter: string) { + (this.getDefaultPreferencesContribution().getPreferencesRenderer()).filterPreferences(filter); } public clearInput(): void { - this.saveState(this.input); + this.saveState(this.input); if (this.inputDisposeListener) { this.inputDisposeListener.dispose(); } super.clearInput(); } + private getDefaultPreferencesContribution(): PreferencesEditorContribution { + return this.defaultPreferencesEditor.getContribution(PreferencesEditorContribution.ID); + } + + private onEditorTextFocussed() { + if (!this.isFocussed) { + this.focus(); + } + } + protected restoreViewState(input: EditorInput) { - const viewState = DefaultPreferencesEditor.VIEW_STATE.get((input).getResource()); + const viewState = PreferencesEditor.VIEW_STATE.get((input).getResource()); if (viewState) { this.getControl().restoreViewState(viewState); } } - private saveState(input: DefaultPreferencesInput) { + private saveState(input: PreferencesEditorInput) { const state = this.getControl().saveViewState(); if (state) { const resource = input.getResource(); - if (DefaultPreferencesEditor.VIEW_STATE.has(resource)) { - DefaultPreferencesEditor.VIEW_STATE.delete(resource); + if (PreferencesEditor.VIEW_STATE.has(resource)) { + PreferencesEditor.VIEW_STATE.delete(resource); } - DefaultPreferencesEditor.VIEW_STATE.set(resource, state); + PreferencesEditor.VIEW_STATE.set(resource, state); } } @@ -143,12 +248,37 @@ export class DefaultPreferencesEditor extends StringEditor { if (this.inputDisposeListener) { this.inputDisposeListener.dispose(); } - if (input instanceof DefaultPreferencesInput) { - this.inputDisposeListener = (input).willDispose(() => this.saveState(input)); + if (input instanceof PreferencesEditorInput) { + this.inputDisposeListener = (input).willDispose(() => this.saveState(input)); } } } +class DefaultPreferencesEditor extends CodeEditor { + + constructor( + domElement: HTMLElement, + options: editorCommon.IEditorOptions, + @IInstantiationService instantiationService: IInstantiationService, + @ICodeEditorService codeEditorService: ICodeEditorService, + @ICommandService commandService: ICommandService, + @IContextKeyService contextKeyService: IContextKeyService + ) { + super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService); + } + + protected _getContributions(): IEditorContributionCtor[] { + let contributions = super._getContributions(); + contributions = contributions.filter(c => { + if (c.prototype === FoldingController.prototype) { + return false; + } + return true; + }); + return contributions; + } +} + export interface IPreferencesRenderer { render(); dispose(); @@ -241,7 +371,6 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR private defaultSettingsEditorContextKey: IContextKey; - private headerWidget: DefaultSettingsHeaderWidget; private settingsGroupTitleRenderer: SettingsGroupTitleRenderer; private filteredMatchesRenderer: FilteredMatchesRenderer; private hiddenAreasRenderer: HiddenAreasRenderer; @@ -254,7 +383,6 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR ) { super(); this.defaultSettingsEditorContextKey = CONTEXT_DEFAULT_SETTINGS_EDITOR.bindTo(contextKeyService); - this.headerWidget = this._register(instantiationService.createInstance(DefaultSettingsHeaderWidget, editor)); this.settingsGroupTitleRenderer = this._register(instantiationService.createInstance(SettingsGroupTitleRenderer, editor)); this.filteredMatchesRenderer = this._register(instantiationService.createInstance(FilteredMatchesRenderer, editor)); this.copySettingActionRenderer = this._register(instantiationService.createInstance(CopySettingActionRenderer, editor, true)); @@ -264,28 +392,21 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR public render() { this.defaultSettingsEditorContextKey.set(true); - this.headerWidget.render(); this.settingsGroupTitleRenderer.render(this.settingsEditorModel.settingsGroups); - this._register(this.headerWidget.onDidChange(value => this.filterPreferences(value))); this.copySettingActionRenderer.render(this.settingsEditorModel.settingsGroups); - this.editor.setScrollTop(0); + this.hiddenAreasRenderer.render(); } public filterPreferences(filter: string) { const filterResult = this.settingsEditorModel.filterSettings(filter); this.filteredMatchesRenderer.render(filterResult); this.settingsGroupTitleRenderer.render(filterResult.filteredGroups); - this.editor.setScrollTop(0); } public collapseAll() { this.settingsGroupTitleRenderer.collapseAll(); } - public setSearchValue(value: string) { - this.headerWidget.setInput(value); - } - dispose() { this.defaultSettingsEditorContextKey.reset(); super.dispose(); @@ -405,12 +526,11 @@ export class HiddenAreasRenderer extends Disposable { ) { super(); for (const hiddenAreProvider of hiddenAreasProviders) { - this._register(hiddenAreProvider.onHiddenAreasChanged(() => this.onHiddenAreasChanged())); + this._register(hiddenAreProvider.onHiddenAreasChanged(() => this.render())); } - this.onHiddenAreasChanged(); } - private onHiddenAreasChanged() { + public render() { const ranges: editorCommon.IRange[] = []; for (const hiddenAreaProvider of this.hiddenAreasProviders) { ranges.push(...hiddenAreaProvider.hiddenAreas); @@ -600,7 +720,7 @@ export class CopySettingActionRenderer extends Disposable { switch (e.target.type) { case editorCommon.MouseTargetType.CONTENT_EMPTY: - if (hasClass(e.target.element, 'copySetting')) { + if (DOM.hasClass(e.target.element, 'copySetting')) { this.onClick(e); } return; @@ -619,7 +739,7 @@ export class CopySettingActionRenderer extends Disposable { let jsonSchema: IJSONSchema = this.getConfigurationsMap()[setting.key]; const actions = this.getActions(setting, jsonSchema); if (actions) { - let elementPosition = getDomNodePagePosition(e.target.element); + let elementPosition = DOM.getDomNodePagePosition(e.target.element); const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 }; this.contextMenuService.showContextMenu({ getAnchor: () => anchor, diff --git a/src/vs/workbench/parts/preferences/browser/preferencesService.ts b/src/vs/workbench/parts/preferences/browser/preferencesService.ts index 4c3bbf4911e..87784e592c1 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesService.ts @@ -7,6 +7,7 @@ import * as network from 'vs/base/common/network'; import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; +import { LinkedMap as Map } from 'vs/base/common/map'; import * as labels from 'vs/base/common/labels'; import { Delayer } from 'vs/base/common/async'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -28,7 +29,7 @@ import { IConfigurationEditingService, ConfigurationTarget, IConfigurationValue import { IPreferencesService, IPreferencesEditorModel, ISettingsEditorModel, IKeybindingsEditorModel, ISetting } from 'vs/workbench/parts/preferences/common/preferences'; import { SettingsEditorModel, DefaultSettingsEditorModel, DefaultKeybindingsEditorModel } from 'vs/workbench/parts/preferences/common/preferencesModels'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { DefaultSettingsInput, DefaultKeybindingsInput, DefaultPreferencesInput } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; +import { PreferencesEditorInput } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { ITextModelResolverService } from 'vs/editor/common/services/resolverService'; import { IQuickOpenService, IPickOpenEntry } from 'vs/workbench/services/quickopen/common/quickOpenService'; import { SettingHandler, UserSettingHandler, WorkspaceSettingHandler } from 'vs/workbench/parts/preferences/browser/preferencesQuickOpen'; @@ -52,11 +53,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic _serviceBrand: any; private configurationTarget: ConfigurationTarget = null; - - private _userSettingsEditorModel: SettingsEditorModel; - private _workspaceSettingsEditorModel: SettingsEditorModel; - private _defaultSettingsEditorModel: DefaultSettingsEditorModel; - private _defaultKeybindingsEditorModel: IKeybindingsEditorModel; + private defaultEditorModels: Map; constructor( @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @@ -75,6 +72,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic @IQuickOpenService private quickOpenService: IQuickOpenService ) { super(); + this.defaultEditorModels = new Map(); this._register(this.editorGroupService.onEditorsChanged(() => { const configurationTarget = this.getConfigurationTargetForCurrentActiveEditor(); if (configurationTarget !== null) { @@ -83,57 +81,43 @@ export class PreferencesService extends Disposable implements IPreferencesServic })); } - public resolvePreferencesEditorModel(uri: URI): TPromise { + public createDefaultPreferencesEditorModel(uri: URI): TPromise { if (PreferencesService.DEFAULT_SETTINGS_URI.fsPath === uri.fsPath) { - return this.getDefaultSettingsEditorModel(); + return this.fetchMostCommonlyUsedSettings() + .then(mostCommonSettings => { + const uri = URI.from({ scheme: PreferencesService.DEFAULT_SETTINGS_URI.scheme, authority: PreferencesService.DEFAULT_SETTINGS_URI.authority, path: PreferencesService.DEFAULT_SETTINGS_URI.path, fragment: '' + this.defaultEditorModels.size }); + const model = this.instantiationService.createInstance(DefaultSettingsEditorModel, uri, mostCommonSettings); + this.defaultEditorModels.set(uri, model); + return model; + }); } if (PreferencesService.DEFAULT_KEY_BINDINGS_URI.fsPath === uri.fsPath) { - return this.getDefaultKeybindingsEditorModel(); - } - - if (this.getEditableSettingsURI(ConfigurationTarget.USER).fsPath === uri.fsPath) { - return this.getUserSettingsEditorModel(); - } - - const workspaceSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE); - if (workspaceSettingsUri && workspaceSettingsUri.fsPath === uri.fsPath) { - return this.getWorkspaceSettingsEditorModel(); + const uri = URI.from({ scheme: PreferencesService.DEFAULT_KEY_BINDINGS_URI.scheme, authority: PreferencesService.DEFAULT_KEY_BINDINGS_URI.authority, path: PreferencesService.DEFAULT_KEY_BINDINGS_URI.path, fragment: '' + this.defaultEditorModels.size }); + const model = this.instantiationService.createInstance(DefaultKeybindingsEditorModel, uri); + this.defaultEditorModels.set(uri, model); + return TPromise.wrap(model); } - return TPromise.wrap(null); + return null; } - public getDefaultSettingsEditorModel(): TPromise { - if (this._defaultSettingsEditorModel) { - return TPromise.wrap(this._defaultSettingsEditorModel); + public resolvePreferencesEditorModel(uri: URI): TPromise { + const model = this.defaultEditorModels.get(uri); + if (model) { + return TPromise.wrap(model); } - return this.fetchMostCommonlyUsedSettings() - .then(mostCommonlyUsedSettings => { - this._defaultSettingsEditorModel = this.instantiationService.createInstance(DefaultSettingsEditorModel, PreferencesService.DEFAULT_SETTINGS_URI, mostCommonlyUsedSettings); - return this._defaultSettingsEditorModel; - }); - } - public getDefaultKeybindingsEditorModel(): TPromise { - if (!this._defaultKeybindingsEditorModel) { - this._defaultKeybindingsEditorModel = this.instantiationService.createInstance(DefaultKeybindingsEditorModel, PreferencesService.DEFAULT_KEY_BINDINGS_URI); + if (this.getEditableSettingsURI(ConfigurationTarget.USER).fsPath === uri.fsPath) { + return this.resolveSettingsEditorModel(ConfigurationTarget.USER); } - return TPromise.wrap(this._defaultKeybindingsEditorModel); - } - public getUserSettingsEditorModel(): TPromise { - if (this._userSettingsEditorModel) { - return TPromise.wrap(this._userSettingsEditorModel); + const workspaceSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE); + if (workspaceSettingsUri && workspaceSettingsUri.fsPath === uri.fsPath) { + return this.resolveSettingsEditorModel(ConfigurationTarget.WORKSPACE); } - return this.resolveSettingsEditorModel(ConfigurationTarget.USER).then(() => this._userSettingsEditorModel); - } - public getWorkspaceSettingsEditorModel(): TPromise { - if (this._workspaceSettingsEditorModel) { - return TPromise.wrap(this._workspaceSettingsEditorModel); - } - return this.resolveSettingsEditorModel(ConfigurationTarget.WORKSPACE).then(() => this._workspaceSettingsEditorModel); + return TPromise.wrap(null); } openGlobalSettings(): TPromise { @@ -154,9 +138,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic openGlobalKeybindingSettings(): TPromise { const emptyContents = '// ' + nls.localize('emptyKeybindingsHeader', "Place your key bindings in this file to overwrite the defaults") + '\n[\n]'; - return this.getDefaultKeybindingsEditorModel() - .then(defaultKeybindingsEditorModel => this.openTwoEditors(DefaultKeybindingsInput.getInstance(this.instantiationService, defaultKeybindingsEditorModel), URI.file(this.environmentService.appKeybindingsPath), emptyContents)) - .then(() => null); + return this.openTwoEditors(this.instantiationService.createInstance(PreferencesEditorInput, PreferencesService.DEFAULT_KEY_BINDINGS_URI, false), URI.file(this.environmentService.appKeybindingsPath), emptyContents).then(() => null); } private openEditableSettings(configurationTarget: ConfigurationTarget, showVisibleEditor: boolean = false): TPromise { @@ -239,35 +221,13 @@ export class PreferencesService extends Disposable implements IPreferencesServic }).then(value => value === userTargetEntry ? ConfigurationTarget.USER : ConfigurationTarget.WORKSPACE); } - private resolveSettingsEditorModel(configurationTarget: ConfigurationTarget): TPromise { + private resolveSettingsEditorModel(configurationTarget: ConfigurationTarget): TPromise { const settingsUri = this.getEditableSettingsURI(configurationTarget); if (settingsUri) { return this.textModelResolverService.createModelReference(settingsUri) - .then(reference => this.onModelResolved(reference.object.textEditorModel, configurationTarget)); - } - return TPromise.wrap(null); - } - - private onModelResolved(model: editorCommon.IModel, configurationTarget: ConfigurationTarget) { - const settingsEditorModel = this.instantiationService.createInstance(SettingsEditorModel, model, configurationTarget); - if (configurationTarget === ConfigurationTarget.USER) { - this._userSettingsEditorModel = settingsEditorModel; - } - if (configurationTarget === ConfigurationTarget.WORKSPACE) { - this._workspaceSettingsEditorModel = settingsEditorModel; - } - model.onWillDispose(() => this.onModelDisposed(configurationTarget)); - } - - private onModelDisposed(configurationTarget: ConfigurationTarget) { - if (configurationTarget === ConfigurationTarget.USER) { - this._userSettingsEditorModel.dispose(); - this._userSettingsEditorModel = null; - } - if (configurationTarget === ConfigurationTarget.WORKSPACE) { - this._workspaceSettingsEditorModel.dispose(); - this._workspaceSettingsEditorModel = null; + .then(reference => this.instantiationService.createInstance(SettingsEditorModel, reference.object.textEditorModel, configurationTarget)); } + return TPromise.wrap(null); } private isEditorFor(editor: IEditor, configurationTarget: ConfigurationTarget): boolean { @@ -324,14 +284,12 @@ export class PreferencesService extends Disposable implements IPreferencesServic if (openDefaultSettings) { const emptySettingsContents = this.getEmptyEditableSettingsContent(configurationTarget); const settingsResource = this.getEditableSettingsURI(configurationTarget); - return this.getDefaultSettingsEditorModel() - .then(defaultSettingsEditorModel => this.openTwoEditors(DefaultSettingsInput.getInstance(this.instantiationService, defaultSettingsEditorModel), settingsResource, emptySettingsContents)) - .then(() => null); + return this.openTwoEditors(this.instantiationService.createInstance(PreferencesEditorInput, PreferencesService.DEFAULT_SETTINGS_URI, true), settingsResource, emptySettingsContents).then(() => null); } return this.openEditableSettings(configurationTarget).then(() => null); } - private openTwoEditors(leftHandDefaultInput: DefaultPreferencesInput, editableResource: URI, defaultEditableContents: string): TPromise { + private openTwoEditors(leftHandDefaultInput: PreferencesEditorInput, editableResource: URI, defaultEditableContents: string): TPromise { // Create as needed and open in editor return this.createIfNotExists(editableResource, defaultEditableContents).then(() => { return this.editorService.createInput({ resource: editableResource }).then(typedRightHandEditableInput => { diff --git a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts index d20b64efc46..d0a4eeba95d 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts @@ -9,7 +9,7 @@ import { Widget } from 'vs/base/browser/ui/widget'; import Event, { Emitter } from 'vs/base/common/event'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference, IViewZone } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; @@ -66,33 +66,11 @@ export class SettingsGroupTitleWidget extends ZoneWidget { } } -class HeaderViewZone implements IViewZone { +export class DefaultSettingsHeaderWidget extends Widget { - private _domNode: HTMLElement; - public id: number; - public heightInPx: number; - - public get domNode(): HTMLElement { - if (!this._domNode) { - this._domNode = DOM.$('.settings-header-view'); - } - return this._domNode; - } - - public get afterLineNumber(): number { - return 0; - } - - public get afterColumn(): number { - return 0; - } -} + public domNode: HTMLElement; -export class DefaultSettingsHeaderWidget extends Widget implements IOverlayWidget { - - private domNode: HTMLElement; - private headerViewZone: HeaderViewZone; - protected headerContainer: HTMLElement; + private headerContainer: HTMLElement; private searchContainer: HTMLElement; private inputBox: InputBox; @@ -102,46 +80,28 @@ export class DefaultSettingsHeaderWidget extends Widget implements IOverlayWidge private _onEnter = this._register(new Emitter()); public onEnter: Event = this._onEnter.event; - protected _onShowDefaults = this._register(new Emitter()); - public onShowDefaults: Event = this._onShowDefaults.event; - - private _onCopySetting = new Emitter(); - public onCopySetting: Event = this._onCopySetting.event; - - constructor(private editor: ICodeEditor, + constructor(parent: HTMLElement, @IContextViewService private contextViewService: IContextViewService, @IContextMenuService private contextMenuService: IContextMenuService, @IInstantiationService private instantiationService: IInstantiationService ) { super(); - this._register(this.editor.onDidChangeCursorPosition(positionChangeEvent => this.onPositionChanged(positionChangeEvent))); - } - - public getId(): string { - return 'editor.overlay.defaultSettingsHeaderWidget'; - } - - public getDomNode(): HTMLElement { - return this.domNode; + this.create(parent); } - public getPosition(): IOverlayWidgetPosition { - return null; - } - - protected create() { - this.domNode = DOM.$('div.settings-header-widget'); + private create(parent: HTMLElement) { + this.domNode = DOM.append(parent, DOM.$('div.settings-header-widget')); this.headerContainer = DOM.append(this.domNode, DOM.$('div.settings-header-container')); const titleContainer = DOM.append(this.headerContainer, DOM.$('div.settings-title-container')); this.createInfoContainer(DOM.append(titleContainer, DOM.$('div.settings-info-container'))); this.createSearchContainer(DOM.append(this.headerContainer, DOM.$('div.settings-search-container'))); } - protected createInfoContainer(infoContainer: HTMLElement) { + private createInfoContainer(infoContainer: HTMLElement) { DOM.append(infoContainer, DOM.$('span')).textContent = localize('defaultSettingsInfo', "Overwrite settings by placing them into your settings file."); } - protected createSearchContainer(searchContainer: HTMLElement) { + private createSearchContainer(searchContainer: HTMLElement) { this.searchContainer = searchContainer; const searchInput = DOM.append(this.searchContainer, DOM.$('div.settings-search-input')); this.inputBox = this._register(new InputBox(searchInput, this.contextViewService, { @@ -153,65 +113,38 @@ export class DefaultSettingsHeaderWidget extends Widget implements IOverlayWidge this.onkeyup(this.inputBox.inputElement, (e) => this._onKeyUp(e)); } - public render(): void { - this.create(); - this.headerViewZone = new HeaderViewZone(); - this.editor.changeViewZones(accessor => { - this.headerViewZone.id = accessor.addZone(this.headerViewZone); - }); + public show() { + DOM.addClass(this.domNode, 'show'); + } - this.editor.addOverlayWidget(this); - this._register(this.editor.onDidLayoutChange(e => this.layout())); - this.layout(); + public hide() { + DOM.removeClass(this.domNode, 'show'); } - public clearInput() { - this.inputBox.value = ''; + public focusTracker(): DOM.IFocusTracker { + return DOM.trackFocus(this.inputBox.inputElement); } - public setInput(value: string) { - this.inputBox.value = value; + public focus() { + this.inputBox.focus(); } - private layout(): void { - const editorLayoutInfo = this.editor.getLayoutInfo(); - this.domNode.style.width = editorLayoutInfo.width - editorLayoutInfo.verticalScrollbarWidth + 'px'; + public layout(editorLayoutInfo: editorCommon.EditorLayoutInfo): void { this.headerContainer.style.width = editorLayoutInfo.width - editorLayoutInfo.verticalScrollbarWidth + 'px'; this.headerContainer.style.paddingLeft = editorLayoutInfo.contentLeft + 'px'; - this.headerContainer.style.paddingRight = editorLayoutInfo.glyphMarginWidth + 'px'; - this.searchContainer.style.width = editorLayoutInfo.contentWidth - editorLayoutInfo.glyphMarginWidth - 20 + 'px'; - this.inputBox.width = editorLayoutInfo.contentWidth - editorLayoutInfo.glyphMarginWidth - 20; - - this.headerViewZone.heightInPx = DOM.getDomNodePagePosition(this.domNode).height; - this.editor.changeViewZones(accessor => { - accessor.layoutZone(this.headerViewZone.id); - }); + this.searchContainer.style.width = editorLayoutInfo.contentWidth - editorLayoutInfo.glyphMarginWidth + 'px'; + this.inputBox.width = editorLayoutInfo.contentWidth - editorLayoutInfo.glyphMarginWidth; } private _onKeyUp(keyboardEvent: IKeyboardEvent): void { switch (keyboardEvent.keyCode) { case KeyCode.Enter: - if (keyboardEvent.ctrlKey) { - this._onCopySetting.fire(); - } else { - this._onEnter.fire(); - } + this._onEnter.fire(); keyboardEvent.preventDefault(); keyboardEvent.stopPropagation(); return; } } - - private onPositionChanged(positionChangeEvent: editorCommon.ICursorPositionChangedEvent) { - if (positionChangeEvent.position.lineNumber < 3) { - this.editor.setScrollTop(0); - } - } - - public dispose() { - this.editor.removeOverlayWidget(this); - super.dispose(); - } } export class FloatingClickWidget extends Widget implements IOverlayWidget { diff --git a/src/vs/workbench/parts/preferences/common/preferences.ts b/src/vs/workbench/parts/preferences/common/preferences.ts index 0a23e6907c0..ce062c84531 100644 --- a/src/vs/workbench/parts/preferences/common/preferences.ts +++ b/src/vs/workbench/parts/preferences/common/preferences.ts @@ -59,11 +59,7 @@ export const IPreferencesService = createDecorator('prefere export interface IPreferencesService { _serviceBrand: any; - getDefaultSettingsEditorModel(): TPromise; - getUserSettingsEditorModel(): TPromise; - getWorkspaceSettingsEditorModel(): TPromise; - getDefaultKeybindingsEditorModel(): TPromise; - + createDefaultPreferencesEditorModel(uri: URI): TPromise; resolvePreferencesEditorModel(uri: URI): TPromise; openGlobalSettings(): TPromise; @@ -76,5 +72,4 @@ export interface IPreferencesService { } export const CONTEXT_DEFAULT_SETTINGS_EDITOR = new RawContextKey('defaultSettingsEditor', false); -export const DEFAULT_EDITOR_COMMAND_COLLAPSE_ALL = 'defaultSettingseditor.action.clearsearchresults'; -export const DEFAULT_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS = 'defaultSettingseditor.action.collapseAll'; \ No newline at end of file +export const DEFAULT_EDITOR_COMMAND_COLLAPSE_ALL = 'defaultSettingseditor.action.clearsearchresults'; \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/common/preferencesModels.ts b/src/vs/workbench/parts/preferences/common/preferencesModels.ts index 2cd82b04cd6..17a0f65600b 100644 --- a/src/vs/workbench/parts/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/parts/preferences/common/preferencesModels.ts @@ -271,7 +271,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements private indent: string; - private _settingsGroups: ISettingsGroup[]; + private _allSettingsGroups: ISettingsGroup[]; private _content: string; private _contentByLines: string[]; @@ -280,7 +280,6 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements super(); const editorConfig = this.configurationService.getConfiguration(); this.indent = editorConfig.editor.insertSpaces ? strings.repeat(' ', editorConfig.editor.tabSize) : '\t'; - // this.indent = ''; } public get uri(): URI { @@ -295,10 +294,10 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements } public get settingsGroups(): ISettingsGroup[] { - if (!this._settingsGroups) { + if (!this._allSettingsGroups) { this.parse(); } - return this._settingsGroups; + return this._allSettingsGroups; } public get mostCommonlyUsedSettings(): ISettingsGroup { @@ -325,7 +324,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements private parse() { const configurations = Registry.as(Extensions.Configuration).getConfigurations(); const allSettingsGroups = configurations.sort(this.compareConfigurationNodes).reduce((result, config) => this.parseConfig(config, result), []); - this._settingsGroups = [this.getMostCommonlyUsedSettings(allSettingsGroups), ...allSettingsGroups]; + this._allSettingsGroups = [this.getMostCommonlyUsedSettings(allSettingsGroups), ...allSettingsGroups]; this._content = this.toContent(this.settingsGroups); } -- GitLab