preferencesEditor.ts 39.4 KB
Newer Older
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { TPromise } from 'vs/base/common/winjs.base';
import * as nls from 'vs/nls';
import URI from 'vs/base/common/uri';
S
Sandeep Somavarapu 已提交
9
import * as DOM from 'vs/base/browser/dom';
10
import { Delayer } from 'vs/base/common/async';
S
Sandeep Somavarapu 已提交
11
import { Dimension, Builder } from 'vs/base/browser/builder';
S
Sandeep Somavarapu 已提交
12 13
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { flatten } from 'vs/base/common/arrays';
S
Sandeep Somavarapu 已提交
14
import { ArrayIterator } from 'vs/base/common/iterator';
S
Sandeep Somavarapu 已提交
15 16
import { IAction } from 'vs/base/common/actions';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
17
import Event, { Emitter } from 'vs/base/common/event';
18 19
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { SideBySideEditor } from 'vs/workbench/browser/parts/editor/sideBySideEditor';
S
Sandeep Somavarapu 已提交
20
import { Registry } from 'vs/platform/platform';
S
Sandeep Somavarapu 已提交
21
import { EditorOptions, toResource } from 'vs/workbench/common/editor';
22 23
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
S
Sandeep Somavarapu 已提交
24 25
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import * as editorCommon from 'vs/editor/common/editorCommon';
S
Sandeep Somavarapu 已提交
26
import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor';
S
Sandeep Somavarapu 已提交
27
import { CodeEditor } from 'vs/editor/browser/codeEditor';
S
Sandeep Somavarapu 已提交
28
import { Range } from 'vs/editor/common/core/range';
29
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
S
Sandeep Somavarapu 已提交
30
import {
S
Sandeep Somavarapu 已提交
31
	IPreferencesService, ISettingsGroup, ISetting, IPreferencesEditorModel, IFilterResult, CONTEXT_DEFAULT_SETTINGS_EDITOR,
S
Sandeep Somavarapu 已提交
32
	DEFAULT_EDITOR_COMMAND_COLLAPSE_ALL, DEFAULT_EDITOR_COMMAND_FOCUS_SEARCH, ISettingsEditorModel
S
Sandeep Somavarapu 已提交
33
} from 'vs/workbench/parts/preferences/common/preferences';
34
import { SettingsEditorModel, DefaultSettingsEditorModel } from 'vs/workbench/parts/preferences/common/preferencesModels';
S
Sandeep Somavarapu 已提交
35
import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
S
Sandeep Somavarapu 已提交
36
import { ICodeEditor, IEditorMouseEvent, IEditorContributionCtor } from 'vs/editor/browser/editorBrowser';
37
import { IContextMenuService, ContextSubMenu } from 'vs/platform/contextview/browser/contextView';
38
import { DefaultSettingsHeaderWidget, SettingsGroupTitleWidget, SettingsCountWidget, EditPreferenceWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
S
Sandeep Somavarapu 已提交
39
import { IContextKeyService, IContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
40
import { CommonEditorRegistry, EditorCommand, Command } from 'vs/editor/common/editorCommonExtensions';
S
Sandeep Somavarapu 已提交
41 42 43 44
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
S
Sandeep Somavarapu 已提交
45 46
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
47
import { IMessageService, Severity } from 'vs/platform/message/common/message';
S
Sandeep Somavarapu 已提交
48 49
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
50
import { ITextModelResolverService } from 'vs/editor/common/services/resolverService';
51
import { RangeHighlightDecorations } from 'vs/workbench/common/editor/rangeDecorations';
52
import { IConfigurationEditingService } from 'vs/workbench/services/configuration/common/configurationEditing';
53 54

// Ignore following contributions
S
Sandeep Somavarapu 已提交
55
import { FoldingController } from 'vs/editor/contrib/folding/browser/folding';
S
Sandeep Somavarapu 已提交
56 57
import { FindController } from 'vs/editor/contrib/find/browser/find';
import { SelectionHighlighter } from 'vs/editor/contrib/find/common/findController';
S
Sandeep Somavarapu 已提交
58 59


60
export class DefaultPreferencesEditorInput extends ResourceEditorInput {
61

62 63
	public static ID = 'workbench.editorinputs.defaultpreferences';

64 65 66
	private _willDispose = new Emitter<void>();
	public willDispose: Event<void> = this._willDispose.event;

67 68 69 70
	constructor(defaultSettingsResource: URI,
		@ITextModelResolverService textModelResolverService: ITextModelResolverService
	) {
		super(nls.localize('settingsEditorName', "Default Settings"), '', defaultSettingsResource, textModelResolverService);
71 72
	}

S
Sandeep Somavarapu 已提交
73
	getTypeId(): string {
74
		return DefaultPreferencesEditorInput.ID;
S
Sandeep Somavarapu 已提交
75
	}
76

S
Sandeep Somavarapu 已提交
77 78 79 80 81
	supportsSplitEditor(): boolean {
		return false;
	}

	matches(other: any): boolean {
82
		if (!super.matches(other)) {
S
Sandeep Somavarapu 已提交
83
			return false;
84
		}
85
		if (!(other instanceof DefaultPreferencesEditorInput)) {
S
Sandeep Somavarapu 已提交
86 87
			return false;
		}
S
Sandeep Somavarapu 已提交
88 89
		return true;
	}
90

S
Sandeep Somavarapu 已提交
91 92 93 94
	dispose() {
		this._willDispose.fire();
		this._willDispose.dispose();
		super.dispose();
95 96 97
	}
}

S
Sandeep Somavarapu 已提交
98
export class DefaultPreferencesEditor extends BaseTextEditor {
99

S
Sandeep Somavarapu 已提交
100
	public static ID: string = 'workbench.editor.defaultPreferences';
101

S
Sandeep Somavarapu 已提交
102
	private defaultSettingHeaderWidget: DefaultSettingsHeaderWidget;
103 104
	private delayedFilterLogging: Delayer<void>;

S
Sandeep Somavarapu 已提交
105 106
	constructor(
		@ITelemetryService telemetryService: ITelemetryService,
S
Sandeep Somavarapu 已提交
107
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
S
Sandeep Somavarapu 已提交
108 109 110 111 112
		@IInstantiationService instantiationService: IInstantiationService,
		@IStorageService storageService: IStorageService,
		@IConfigurationService configurationService: IConfigurationService,
		@IThemeService themeService: IThemeService,
		@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
S
Sandeep Somavarapu 已提交
113 114
		@IPreferencesService private preferencesService: IPreferencesService,
		@IModelService private modelService: IModelService,
115
		@IModeService modeService: IModeService,
S
Sandeep Somavarapu 已提交
116
	) {
117
		super(DefaultPreferencesEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, modeService);
118
		this.delayedFilterLogging = new Delayer<void>(1000);
S
Sandeep Somavarapu 已提交
119 120
	}

121
	public createEditorControl(parent: Builder, configuration: editorCommon.IEditorOptions): editorCommon.IEditor {
S
Sandeep Somavarapu 已提交
122
		const parentContainer = parent.getHTMLElement();
S
Sandeep Somavarapu 已提交
123

S
Sandeep Somavarapu 已提交
124 125
		this.defaultSettingHeaderWidget = this._register(this.instantiationService.createInstance(DefaultSettingsHeaderWidget, parentContainer));
		this._register(this.defaultSettingHeaderWidget.onDidChange(value => this.filterPreferences(value)));
S
Sandeep Somavarapu 已提交
126
		this._register(this.defaultSettingHeaderWidget.onEnter(value => this.focusNextPreference()));
127

128
		const defaultPreferencesEditor = this.instantiationService.createInstance(DefaultPreferencesCodeEditor, parentContainer, configuration);
129

S
Sandeep Somavarapu 已提交
130
		return defaultPreferencesEditor;
131 132
	}

133 134
	protected getConfigurationOverrides(): editorCommon.IEditorOptions {
		const options = super.getConfigurationOverrides();
135
		options.readOnly = true;
136
		if (this.input) {
S
Sandeep Somavarapu 已提交
137 138 139 140 141 142
			options.lineNumbers = 'off';
			options.renderLineHighlight = 'none';
			options.scrollBeyondLastLine = false;
			options.folding = false;
			options.renderWhitespace = 'none';
			options.wrappingColumn = 0;
S
Sandeep Somavarapu 已提交
143
			options.renderIndentGuides = false;
S
Sandeep Somavarapu 已提交
144
			options.rulers = [];
S
Sandeep Somavarapu 已提交
145
		}
S
Sandeep Somavarapu 已提交
146 147 148
		return options;
	}

S
Sandeep Somavarapu 已提交
149
	setInput(input: DefaultPreferencesEditorInput, options: EditorOptions): TPromise<void> {
150
		return super.setInput(input, options).then(() => this.updateInput());
S
Sandeep Somavarapu 已提交
151 152 153
	}

	public layout(dimension: Dimension) {
S
Sandeep Somavarapu 已提交
154
		this.defaultSettingHeaderWidget.layout(dimension);
155
		const headerHeight = DOM.getTotalHeight(this.defaultSettingHeaderWidget.domNode);
S
Sandeep Somavarapu 已提交
156
		this.getControl().layout({
157
			height: dimension.height - headerHeight,
S
Sandeep Somavarapu 已提交
158 159
			width: dimension.width
		});
S
Sandeep Somavarapu 已提交
160 161 162
	}

	public focus(): void {
163
		if (this.input) {
S
Sandeep Somavarapu 已提交
164 165 166 167 168 169
			this.defaultSettingHeaderWidget.focus();
		} else {
			super.focus();
		}
	}

S
Sandeep Somavarapu 已提交
170 171
	private updateInput(): TPromise<void> {
		return this.input.resolve()
172 173 174 175
			.then(editorModel => TPromise.join<any>([
				editorModel.load(),
				// Default preferences editor is always part of side by side editor hence getting the master preferences model from active editor
				// TODO:@sandy check with Ben
S
Sandeep Somavarapu 已提交
176
				this.preferencesService.resolvePreferencesEditorModel(toResource(this.editorService.getActiveEditorInput(), { supportSideBySide: true }))
177 178
			]))
			.then(([editorModel, preferencesModel]) => (<DefaultPreferencesCodeEditor>this.getControl()).setModels((<ResourceEditorModel>editorModel).textEditorModel, <SettingsEditorModel>preferencesModel));
S
Sandeep Somavarapu 已提交
179 180 181
	}

	private filterPreferences(filter: string) {
182
		this.delayedFilterLogging.trigger(() => this.reportFilteringUsed(filter));
S
#17646:  
Sandeep Somavarapu 已提交
183
		(<DefaultSettingsRenderer>this.getDefaultPreferencesContribution().getPreferencesRenderer()).filterPreferences(filter.trim());
184 185
	}

S
Sandeep Somavarapu 已提交
186 187 188 189
	private focusNextPreference() {
		(<DefaultSettingsRenderer>this.getDefaultPreferencesContribution().getPreferencesRenderer()).focusNextSetting();
	}

190
	public clearInput(): void {
S
Sandeep Somavarapu 已提交
191
		this.getControl().setModel(null);
192 193 194
		super.clearInput();
	}

S
Sandeep Somavarapu 已提交
195
	private getDefaultPreferencesContribution(): PreferencesEditorContribution {
196
		return (<CodeEditor>this.getControl()).getContribution<PreferencesEditorContribution>(DefaultSettingsEditorContribution.ID);
197
	}
198

199 200 201 202 203
	private reportFilteringUsed(filter: string): void {
		let data = {};
		data['filter'] = filter;
		this.telemetryService.publicLog('defaultSettings.filter', data);
	}
S
Sandeep Somavarapu 已提交
204 205
}

S
Sandeep Somavarapu 已提交
206
class DefaultPreferencesCodeEditor extends CodeEditor {
S
Sandeep Somavarapu 已提交
207

208 209
	private _settingsModel: SettingsEditorModel;

S
Sandeep Somavarapu 已提交
210 211
	protected _getContributions(): IEditorContributionCtor[] {
		let contributions = super._getContributions();
S
Sandeep Somavarapu 已提交
212
		let skipContributions = [FoldingController.prototype, SelectionHighlighter.prototype, FindController.prototype];
S
Sandeep Somavarapu 已提交
213
		contributions = contributions.filter(c => skipContributions.indexOf(c.prototype) === -1);
214 215
		contributions.push(DefaultSettingsEditorContribution);
		return contributions;
S
Sandeep Somavarapu 已提交
216
	}
217 218 219 220 221 222 223 224 225

	setModels(model: editorCommon.IModel, settingsModel: SettingsEditorModel): void {
		this._settingsModel = settingsModel;
		return super.setModel(model);
	}

	get settingsModel(): SettingsEditorModel {
		return this._settingsModel;
	}
S
Sandeep Somavarapu 已提交
226 227
}

228 229
export interface IPreferencesRenderer {
	render();
230
	updatePreference(setting: ISetting, value: any): void;
231 232 233
	dispose();
}

234
export abstract class PreferencesEditorContribution extends Disposable implements editorCommon.IEditorContribution {
S
Sandeep Somavarapu 已提交
235

236
	private preferencesRenderer: IPreferencesRenderer;
S
Sandeep Somavarapu 已提交
237

238 239 240
	constructor(protected editor: ICodeEditor,
		@IInstantiationService protected instantiationService: IInstantiationService,
		@IPreferencesService protected preferencesService: IPreferencesService
S
Sandeep Somavarapu 已提交
241 242 243 244 245 246 247
	) {
		super();
		this._register(editor.onDidChangeModel(() => this.onModelChanged()));
	}

	private onModelChanged(): void {
		const model = this.editor.getModel();
248 249 250 251 252 253
		this.disposePreferencesRenderer();
		if (model) {
			this.preferencesService.resolvePreferencesEditorModel(model.uri)
				.then(editorModel => {
					if (editorModel) {
						this.preferencesRenderer = this.createPreferencesRenderer(editorModel);
S
Sandeep Somavarapu 已提交
254 255 256
						if (this.preferencesRenderer) {
							this.preferencesRenderer.render();
						}
257 258 259 260
					}
				});
		}
	}
S
Sandeep Somavarapu 已提交
261

S
Sandeep Somavarapu 已提交
262 263
	getPreferencesRenderer(): IPreferencesRenderer {
		return this.preferencesRenderer;
264 265
	}

266
	protected abstract createPreferencesRenderer(editorModel: IPreferencesEditorModel): IPreferencesRenderer
267
	abstract getId(): string;
268 269 270 271 272 273 274 275 276 277 278 279 280 281

	private disposePreferencesRenderer() {
		if (this.preferencesRenderer) {
			this.preferencesRenderer.dispose();
			this.preferencesRenderer = null;
		}
	}

	public dispose() {
		this.disposePreferencesRenderer();
		super.dispose();
	}
}

282
export class DefaultSettingsEditorContribution extends PreferencesEditorContribution implements editorCommon.IEditorContribution {
283 284 285

	static ID: string = 'editor.contrib.defaultsettings';

286 287
	protected createPreferencesRenderer(editorModel: IPreferencesEditorModel): IPreferencesRenderer {
		if (editorModel instanceof DefaultSettingsEditorModel) {
288
			return this.instantiationService.createInstance(DefaultSettingsRenderer, this.editor, editorModel, (<DefaultPreferencesCodeEditor>this.editor).settingsModel);
289 290 291
		}
		return null;
	}
292 293 294 295

	getId(): string {
		return DefaultSettingsEditorContribution.ID;
	}
296 297 298 299
}

@editorContribution
export class SettingsEditorContribution extends PreferencesEditorContribution implements editorCommon.IEditorContribution {
300 301 302 303 304 305 306

	static ID: string = 'editor.contrib.settings';

	getId(): string {
		return SettingsEditorContribution.ID;
	}

307 308 309 310 311 312 313 314
	protected createPreferencesRenderer(editorModel: IPreferencesEditorModel): IPreferencesRenderer {
		if (editorModel instanceof SettingsEditorModel) {
			return this.instantiationService.createInstance(SettingsRenderer, this.editor, editorModel);
		}
		return null;
	}
}

315 316
export class SettingsRenderer extends Disposable implements IPreferencesRenderer {

317 318 319
	private initializationPromise: TPromise<void>;
	private settingHighlighter: SettingHighlighter;
	private editSettingActionRenderer: EditSettingRenderer;
S
Sandeep Somavarapu 已提交
320
	private modelChangeDelayer: Delayer<void> = new Delayer<void>(200);
321 322 323

	constructor(protected editor: ICodeEditor, protected settingsEditorModel: SettingsEditorModel,
		@IPreferencesService protected preferencesService: IPreferencesService,
324 325 326
		@ITelemetryService private telemetryService: ITelemetryService,
		@IConfigurationEditingService private configurationEditingService: IConfigurationEditingService,
		@IMessageService private messageService: IMessageService,
327 328 329
		@IInstantiationService protected instantiationService: IInstantiationService
	) {
		super();
330 331
		this.settingHighlighter = this._register(instantiationService.createInstance(SettingHighlighter, editor));
		this.initializationPromise = this.initialize();
332 333
	}

S
Sandeep Somavarapu 已提交
334
	public render(): void {
335 336 337 338 339 340 341 342 343 344 345
		this.initializationPromise.then(() => this.editSettingActionRenderer.render(this.settingsEditorModel.settingsGroups));
	}

	private initialize(): TPromise<void> {
		return this.preferencesService.createDefaultPreferencesEditorModel(this.preferencesService.defaultSettingsResource)
			.then(defaultSettingsModel => {
				this.editSettingActionRenderer = this._register(this.instantiationService.createInstance(EditSettingRenderer, this.editor, this.settingsEditorModel, defaultSettingsModel, this.settingHighlighter));
				this._register(this.editor.getModel().onDidChangeContent(() => this.modelChangeDelayer.trigger(() => this.onModelChanged())));
				this._register(this.editSettingActionRenderer.onUpdateSetting(({setting, value}) => this.updatePreference(setting, value)));
				return null;
			});
346
	}
S
Fixes:  
Sandeep Somavarapu 已提交
347

S
Sandeep Somavarapu 已提交
348 349 350 351 352
	private onModelChanged(): void {
		if (!this.editor.getModel()) {
			// model could have been disposed during the delay
			return;
		}
S
Fixes:  
Sandeep Somavarapu 已提交
353 354
		this.render();
	}
355 356 357 358 359 360 361 362 363 364 365 366

	public updatePreference(setting: ISetting, value: any): void {
		this.telemetryService.publicLog('defaultSettingsActions.copySetting', { userConfigurationKeys: [setting.key] });
		this.configurationEditingService.writeConfiguration(this.settingsEditorModel.configurationTarget, { key: setting.key, value }, { writeToBuffer: true, autoSave: true })
			.then(() => this.onSettingUpdated(setting), error => this.messageService.show(Severity.Error, error));
	}

	private onSettingUpdated(setting: ISetting) {
		this.editor.focus();
		setting = this.settingsEditorModel.getSetting(setting.key);
		// TODO:@sandy Selection range should be template range
		this.editor.setSelection(setting.valueRange);
S
Sandeep Somavarapu 已提交
367
		this.settingHighlighter.highlight(this.settingsEditorModel.getSetting(setting.key), true);
368
	}
369 370
}

371 372
export class DefaultSettingsRenderer extends Disposable implements IPreferencesRenderer {

S
Sandeep Somavarapu 已提交
373 374
	private defaultSettingsEditorContextKey: IContextKey<boolean>;

375
	private settingHighlighter: SettingHighlighter;
S
Sandeep Somavarapu 已提交
376 377
	private settingsGroupTitleRenderer: SettingsGroupTitleRenderer;
	private filteredMatchesRenderer: FilteredMatchesRenderer;
378
	private filteredSettingsNavigationRenderer: FilteredSettingsNavigationRenderer;
S
Sandeep Somavarapu 已提交
379
	private hiddenAreasRenderer: HiddenAreasRenderer;
380
	private editSettingActionRenderer: EditSettingRenderer;
S
Push:  
Sandeep Somavarapu 已提交
381
	private settingsCountWidget: SettingsCountWidget;
382

383 384
	constructor(protected editor: ICodeEditor, protected defaultSettingsEditorModel: DefaultSettingsEditorModel,
		private settingsEditorModel: SettingsEditorModel,
385
		@IPreferencesService protected preferencesService: IPreferencesService,
S
Sandeep Somavarapu 已提交
386
		@IContextKeyService contextKeyService: IContextKeyService,
387
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
388 389 390
		@IInstantiationService protected instantiationService: IInstantiationService
	) {
		super();
S
Sandeep Somavarapu 已提交
391
		this.defaultSettingsEditorContextKey = CONTEXT_DEFAULT_SETTINGS_EDITOR.bindTo(contextKeyService);
392
		this.settingHighlighter = this._register(instantiationService.createInstance(SettingHighlighter, editor));
S
Sandeep Somavarapu 已提交
393 394
		this.settingsGroupTitleRenderer = this._register(instantiationService.createInstance(SettingsGroupTitleRenderer, editor));
		this.filteredMatchesRenderer = this._register(instantiationService.createInstance(FilteredMatchesRenderer, editor));
395
		this.filteredSettingsNavigationRenderer = this._register(instantiationService.createInstance(FilteredSettingsNavigationRenderer, editor, this.settingHighlighter));
396 397 398 399
		this.editSettingActionRenderer = this._register(instantiationService.createInstance(EditSettingRenderer, editor, defaultSettingsEditorModel, settingsEditorModel, this.settingHighlighter));
		this._register(this.editSettingActionRenderer.onUpdateSetting(({setting, value}) => this.updatePreference(setting, value)));
		this.settingsCountWidget = this._register(instantiationService.createInstance(SettingsCountWidget, editor, this.getCount(defaultSettingsEditorModel.settingsGroups)));
		const paranthesisHidingRenderer = this._register(instantiationService.createInstance(StaticContentHidingRenderer, editor, defaultSettingsEditorModel.settingsGroups));
S
Sandeep Somavarapu 已提交
400
		this.hiddenAreasRenderer = this._register(instantiationService.createInstance(HiddenAreasRenderer, editor, [this.settingsGroupTitleRenderer, this.filteredMatchesRenderer, paranthesisHidingRenderer]));
S
Sandeep Somavarapu 已提交
401 402

		this._register(this.settingsGroupTitleRenderer.onHiddenAreasChanged(() => this.hiddenAreasRenderer.render()));
403 404 405
	}

	public render() {
S
Sandeep Somavarapu 已提交
406
		this.defaultSettingsEditorContextKey.set(true);
407 408
		this.settingsGroupTitleRenderer.render(this.defaultSettingsEditorModel.settingsGroups);
		this.editSettingActionRenderer.render(this.defaultSettingsEditorModel.settingsGroups);
S
Push:  
Sandeep Somavarapu 已提交
409
		this.settingsCountWidget.render();
S
Sandeep Somavarapu 已提交
410
		this.hiddenAreasRenderer.render();
411
		this.filteredSettingsNavigationRenderer.render([]);
S
Push:  
Sandeep Somavarapu 已提交
412
		this.settingsGroupTitleRenderer.showGroup(1);
S
Sandeep Somavarapu 已提交
413
		this.hiddenAreasRenderer.render();
S
Sandeep Somavarapu 已提交
414 415 416
	}

	public filterPreferences(filter: string) {
417
		const filterResult = this.defaultSettingsEditorModel.filterSettings(filter);
S
Sandeep Somavarapu 已提交
418 419
		this.filteredMatchesRenderer.render(filterResult);
		this.settingsGroupTitleRenderer.render(filterResult.filteredGroups);
S
Push:  
Sandeep Somavarapu 已提交
420 421 422
		this.settingsCountWidget.show(this.getCount(filterResult.filteredGroups));

		if (!filter) {
423
			this.filteredSettingsNavigationRenderer.render([]);
S
Push:  
Sandeep Somavarapu 已提交
424
			this.settingsGroupTitleRenderer.showGroup(1);
S
Sandeep Somavarapu 已提交
425
		} else {
426
			this.filteredSettingsNavigationRenderer.render(filterResult.filteredGroups);
S
Push:  
Sandeep Somavarapu 已提交
427
		}
S
Sandeep Somavarapu 已提交
428
		this.hiddenAreasRenderer.render();
S
Sandeep Somavarapu 已提交
429 430
	}

S
Sandeep Somavarapu 已提交
431
	public focusNextSetting(): void {
432
		const setting = this.filteredSettingsNavigationRenderer.next();
S
Sandeep Somavarapu 已提交
433 434 435
		if (setting) {
			this.settingsGroupTitleRenderer.showSetting(setting);
		}
S
Sandeep Somavarapu 已提交
436 437
	}

S
Sandeep Somavarapu 已提交
438 439 440 441
	public collapseAll() {
		this.settingsGroupTitleRenderer.collapseAll();
	}

442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
	public updatePreference(setting: ISetting, value: any): void {
		const settingsEditor = this.getEditableSettingsEditor();
		if (settingsEditor) {
			settingsEditor.getContribution<PreferencesEditorContribution>(SettingsEditorContribution.ID).getPreferencesRenderer().updatePreference(setting, value);
		}
	}

	private getEditableSettingsEditor(): editorCommon.ICommonCodeEditor {
		return this.editorService.getVisibleEditors()
			.filter(editor => {
				if (editorCommon.isCommonCodeEditor(editor.getControl())) {
					return (<editorCommon.ICommonCodeEditor>editor.getControl()).getModel().uri.fsPath === this.settingsEditorModel.uri.fsPath;
				}
			})
			.map(editor => <editorCommon.ICommonCodeEditor>editor.getControl())[0];
	}

S
Push:  
Sandeep Somavarapu 已提交
459 460 461 462 463 464 465 466 467 468
	private getCount(settingsGroups: ISettingsGroup[]): number {
		let count = 0;
		for (const group of settingsGroups) {
			for (const section of group.sections) {
				count += section.settings.length;
			}
		}
		return count;
	}

S
Sandeep Somavarapu 已提交
469
	dispose() {
470
		this.defaultSettingsEditorContextKey.set(false);
S
Sandeep Somavarapu 已提交
471
		super.dispose();
472 473 474
	}
}

S
Sandeep Somavarapu 已提交
475 476 477
export interface HiddenAreasProvider {
	hiddenAreas: editorCommon.IRange[];
}
478

S
Sandeep Somavarapu 已提交
479
export class StaticContentHidingRenderer extends Disposable implements HiddenAreasProvider {
480

S
Sandeep Somavarapu 已提交
481
	constructor(private editor: ICodeEditor, private settingsGroups: ISettingsGroup[]
482 483
	) {
		super();
484 485
	}

S
Sandeep Somavarapu 已提交
486 487 488 489 490 491
	get hiddenAreas(): editorCommon.IRange[] {
		const model = this.editor.getModel();
		return [
			{
				startLineNumber: 1,
				startColumn: model.getLineMinColumn(1),
S
Sandeep Somavarapu 已提交
492 493
				endLineNumber: 2,
				endColumn: model.getLineMaxColumn(2)
S
Sandeep Somavarapu 已提交
494 495
			},
			{
S
Sandeep Somavarapu 已提交
496 497 498 499 500 501 502 503
				startLineNumber: this.settingsGroups[0].range.endLineNumber + 1,
				startColumn: model.getLineMinColumn(this.settingsGroups[0].range.endLineNumber + 1),
				endLineNumber: this.settingsGroups[0].range.endLineNumber + 4,
				endColumn: model.getLineMaxColumn(this.settingsGroups[0].range.endLineNumber + 4)
			},
			{
				startLineNumber: model.getLineCount() - 1,
				startColumn: model.getLineMinColumn(model.getLineCount() - 1),
S
Sandeep Somavarapu 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
				endLineNumber: model.getLineCount(),
				endColumn: model.getLineMaxColumn(model.getLineCount())
			}
		];
	}

}

export class SettingsGroupTitleRenderer extends Disposable implements HiddenAreasProvider {

	private _onHiddenAreasChanged: Emitter<void> = new Emitter<void>();
	get onHiddenAreasChanged(): Event<void> { return this._onHiddenAreasChanged.event; };

	private settingsGroups: ISettingsGroup[];
	private hiddenGroups: ISettingsGroup[] = [];
	private settingsGroupTitleWidgets: SettingsGroupTitleWidget[];
	private disposables: IDisposable[] = [];

	constructor(private editor: ICodeEditor,
		@IInstantiationService private instantiationService: IInstantiationService
	) {
		super();
	}

	public get hiddenAreas(): editorCommon.IRange[] {
		const hiddenAreas: editorCommon.IRange[] = [];
		for (const group of this.hiddenGroups) {
			hiddenAreas.push(group.range);
		}
		return hiddenAreas;
	}

	public render(settingsGroups: ISettingsGroup[]) {
		this.disposeWidgets();
		this.settingsGroups = settingsGroups.slice();
		this.settingsGroupTitleWidgets = [];
		for (const group of this.settingsGroups.slice().reverse()) {
			const settingsGroupTitleWidget = this.instantiationService.createInstance(SettingsGroupTitleWidget, this.editor, group);
			settingsGroupTitleWidget.render();
			this.settingsGroupTitleWidgets.push(settingsGroupTitleWidget);
			this.disposables.push(settingsGroupTitleWidget);
			this.disposables.push(settingsGroupTitleWidget.onToggled(collapsed => this.onToggled(collapsed, settingsGroupTitleWidget.settingsGroup)));
S
Sandeep Somavarapu 已提交
546
		}
S
Fixes:  
Sandeep Somavarapu 已提交
547
		this.settingsGroupTitleWidgets.reverse();
S
Sandeep Somavarapu 已提交
548 549
	}

S
Push:  
Sandeep Somavarapu 已提交
550 551 552
	public showGroup(group: number) {
		this.hiddenGroups = this.settingsGroups.filter((g, i) => i !== group - 1);
		for (const groupTitleWidget of this.settingsGroupTitleWidgets.filter((g, i) => i !== group - 1)) {
S
Sandeep Somavarapu 已提交
553
			groupTitleWidget.toggleCollapse(true);
S
Push:  
Sandeep Somavarapu 已提交
554 555 556 557
		}
		this._onHiddenAreasChanged.fire();
	}

S
Sandeep Somavarapu 已提交
558 559 560 561 562 563 564 565 566
	public showSetting(setting: ISetting): void {
		const settingsGroupTitleWidget = this.settingsGroupTitleWidgets.filter(widget => Range.containsRange(widget.settingsGroup.range, setting.range))[0];
		if (settingsGroupTitleWidget && settingsGroupTitleWidget.isCollapsed()) {
			settingsGroupTitleWidget.toggleCollapse(false);
			this.hiddenGroups.splice(this.hiddenGroups.indexOf(settingsGroupTitleWidget.settingsGroup), 1);
			this._onHiddenAreasChanged.fire();
		}
	}

S
Sandeep Somavarapu 已提交
567 568 569 570
	public collapseAll() {
		this.editor.setPosition({ lineNumber: 1, column: 1 });
		this.hiddenGroups = this.settingsGroups.slice();
		for (const groupTitleWidget of this.settingsGroupTitleWidgets) {
S
Sandeep Somavarapu 已提交
571
			groupTitleWidget.toggleCollapse(true);
572
		}
S
Sandeep Somavarapu 已提交
573 574 575 576 577 578 579 580 581 582 583
		this._onHiddenAreasChanged.fire();
	}

	private onToggled(collapsed: boolean, group: ISettingsGroup) {
		const index = this.hiddenGroups.indexOf(group);
		if (collapsed) {
			const currentPosition = this.editor.getPosition();
			if (group.range.startLineNumber <= currentPosition.lineNumber && group.range.endLineNumber >= currentPosition.lineNumber) {
				this.editor.setPosition({ lineNumber: group.range.startLineNumber - 1, column: 1 });
			}
			this.hiddenGroups.push(group);
584
		} else {
S
Sandeep Somavarapu 已提交
585
			this.hiddenGroups.splice(index, 1);
S
Sandeep Somavarapu 已提交
586
		}
S
Sandeep Somavarapu 已提交
587
		this._onHiddenAreasChanged.fire();
S
Sandeep Somavarapu 已提交
588 589
	}

S
Sandeep Somavarapu 已提交
590 591 592
	private disposeWidgets() {
		this.hiddenGroups = [];
		this.disposables = dispose(this.disposables);
593 594
	}

S
Sandeep Somavarapu 已提交
595 596 597 598 599 600 601 602 603 604 605 606
	public dispose() {
		this.disposeWidgets();
		super.dispose();
	}
}

export class HiddenAreasRenderer extends Disposable {

	constructor(private editor: ICodeEditor, private hiddenAreasProviders: HiddenAreasProvider[],
		@IInstantiationService private instantiationService: IInstantiationService
	) {
		super();
S
Sandeep Somavarapu 已提交
607 608
	}

S
Sandeep Somavarapu 已提交
609
	public render() {
S
Sandeep Somavarapu 已提交
610 611 612 613 614 615
		const ranges: editorCommon.IRange[] = [];
		for (const hiddenAreaProvider of this.hiddenAreasProviders) {
			ranges.push(...hiddenAreaProvider.hiddenAreas);
		}
		this.editor.setHiddenAreas(ranges);
	}
S
Sandeep Somavarapu 已提交
616 617 618 619 620

	public dispose() {
		this.editor.setHiddenAreas([]);
		super.dispose();
	}
S
Sandeep Somavarapu 已提交
621 622 623 624 625 626 627 628 629 630 631 632 633 634
}

export class FilteredMatchesRenderer extends Disposable implements HiddenAreasProvider {

	private decorationIds: string[] = [];
	public hiddenAreas: editorCommon.IRange[] = [];

	constructor(private editor: ICodeEditor,
		@IInstantiationService private instantiationService: IInstantiationService
	) {
		super();
	}

	public render(result: IFilterResult): void {
635
		const model = this.editor.getModel();
S
Sandeep Somavarapu 已提交
636
		this.hiddenAreas = [];
637
		this.editor.changeDecorations(changeAccessor => {
S
Sandeep Somavarapu 已提交
638 639 640
			this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, []);
		});
		if (result) {
641 642 643
			this.hiddenAreas = this.computeHiddenRanges(result.filteredGroups, result.allGroups, model);
			this.editor.changeDecorations(changeAccessor => {
				this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, flatten(result.matches.values()).map(match => this.createDecoration(match, model)));
S
Sandeep Somavarapu 已提交
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
			});
		}
	}

	private createDecoration(range: editorCommon.IRange, model: editorCommon.IModel): editorCommon.IModelDeltaDecoration {
		return {
			range,
			options: {
				stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
				className: 'findMatch'
			}
		};
	}

	private computeHiddenRanges(filteredGroups: ISettingsGroup[], allSettingsGroups: ISettingsGroup[], model: editorCommon.IModel): editorCommon.IRange[] {
		const notMatchesRanges: editorCommon.IRange[] = [];
		for (const group of allSettingsGroups) {
			const filteredGroup = filteredGroups.filter(g => g.title === group.title)[0];
			if (!filteredGroup) {
				notMatchesRanges.push({
					startLineNumber: group.range.startLineNumber - 1,
					startColumn: model.getLineMinColumn(group.range.startLineNumber - 1),
					endLineNumber: group.range.endLineNumber,
					endColumn: model.getLineMaxColumn(group.range.endLineNumber),
				});
			} else {
670
				for (const section of group.sections) {
671 672 673
					if (section.titleRange) {
						if (!this.containsLine(section.titleRange.startLineNumber, filteredGroup)) {
							notMatchesRanges.push(this.createCompleteRange(section.titleRange, model));
S
Sandeep Somavarapu 已提交
674 675
						}
					}
676
					for (const setting of section.settings) {
S
Sandeep Somavarapu 已提交
677 678
						if (!this.containsLine(setting.range.startLineNumber, filteredGroup)) {
							notMatchesRanges.push(this.createCompleteRange(setting.range, model));
679 680 681 682 683
						}
					}
				}
			}
		}
S
Sandeep Somavarapu 已提交
684 685 686 687 688 689 690 691 692
		return notMatchesRanges;
	}

	private containsLine(lineNumber: number, settingsGroup: ISettingsGroup): boolean {
		if (settingsGroup.titleRange && lineNumber >= settingsGroup.titleRange.startLineNumber && lineNumber <= settingsGroup.titleRange.endLineNumber) {
			return true;
		}

		for (const section of settingsGroup.sections) {
693
			if (section.titleRange && lineNumber >= section.titleRange.startLineNumber && lineNumber <= section.titleRange.endLineNumber) {
S
Sandeep Somavarapu 已提交
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
				return true;
			}

			for (const setting of section.settings) {
				if (lineNumber >= setting.range.startLineNumber && lineNumber <= setting.range.endLineNumber) {
					return true;
				}
			}
		}
		return false;
	}

	private createCompleteRange(range: editorCommon.IRange, model: editorCommon.IModel): editorCommon.IRange {
		return {
			startLineNumber: range.startLineNumber,
			startColumn: model.getLineMinColumn(range.startLineNumber),
			endLineNumber: range.endLineNumber,
			endColumn: model.getLineMaxColumn(range.endLineNumber)
		};
	}

	public dispose() {
716 717
		if (this.decorationIds) {
			this.decorationIds = this.editor.changeDecorations(changeAccessor => {
718
				return changeAccessor.deltaDecorations(this.decorationIds, []);
S
Sandeep Somavarapu 已提交
719 720 721
			});
		}
		super.dispose();
S
Sandeep Somavarapu 已提交
722 723 724
	}
}

725
class FilteredSettingsNavigationRenderer extends Disposable {
S
Sandeep Somavarapu 已提交
726 727 728

	private iterator: ArrayIterator<ISetting>;

729
	constructor(private editor: ICodeEditor, private settingHighlighter: SettingHighlighter) {
S
Sandeep Somavarapu 已提交
730 731 732
		super();
	}

733
	public next(): ISetting {
S
Sandeep Somavarapu 已提交
734 735
		let setting = this.iterator.next() || this.iterator.first();
		if (setting) {
S
Sandeep Somavarapu 已提交
736
			this.settingHighlighter.highlight(setting, true);
S
Sandeep Somavarapu 已提交
737
			return setting;
S
Sandeep Somavarapu 已提交
738
		}
S
Sandeep Somavarapu 已提交
739
		return null;
S
Sandeep Somavarapu 已提交
740 741 742
	}

	public render(filteredGroups: ISettingsGroup[]) {
743
		this.settingHighlighter.clear(true);
S
Sandeep Somavarapu 已提交
744 745 746 747 748 749 750 751 752 753
		const settings: ISetting[] = [];
		for (const group of filteredGroups) {
			for (const section of group.sections) {
				settings.push(...section.settings);
			}
		}
		this.iterator = new ArrayIterator<ISetting>(settings);
	}
}

754
class EditSettingRenderer extends Disposable {
755

756 757
	private editPreferenceWidgetForCusorPosition: EditPreferenceWidget<ISetting>;
	private editPreferenceWidgetForMouseMove: EditPreferenceWidget<ISetting>;
S
Sandeep Somavarapu 已提交
758

759
	private settingsGroups: ISettingsGroup[];
760
	private toggleEditPreferencesForMouseMoveDelayer: Delayer<void>;
761

762 763
	private _onUpdateSetting: Emitter<{ setting: ISetting, value: any }> = new Emitter<{ setting: ISetting, value: any }>();
	public readonly onUpdateSetting: Event<{ setting: ISetting, value: any }> = this._onUpdateSetting.event;
764

765 766 767
	constructor(private editor: ICodeEditor, private masterSettingsModel: ISettingsEditorModel,
		private otherSettingsModel: ISettingsEditorModel,
		private settingHighlighter: SettingHighlighter,
768 769
		@IPreferencesService private preferencesService: IPreferencesService,
		@IInstantiationService private instantiationService: IInstantiationService,
S
Sandeep Somavarapu 已提交
770 771 772
		@IContextMenuService private contextMenuService: IContextMenuService
	) {
		super();
773

774 775 776
		this.editPreferenceWidgetForCusorPosition = this._register(this.instantiationService.createInstance(EditPreferenceWidget, editor));
		this.editPreferenceWidgetForMouseMove = this._register(this.instantiationService.createInstance(EditPreferenceWidget, editor));
		this.toggleEditPreferencesForMouseMoveDelayer = new Delayer<void>(75);
777

778 779
		this._register(this.editPreferenceWidgetForCusorPosition.onClick(setting => this.onEditSettingClicked(this.editPreferenceWidgetForCusorPosition)));
		this._register(this.editPreferenceWidgetForMouseMove.onClick(setting => this.onEditSettingClicked(this.editPreferenceWidgetForMouseMove)));
780

781 782
		this._register(this.editPreferenceWidgetForCusorPosition.onMouseOver(setting => this.onMouseOver(this.editPreferenceWidgetForCusorPosition)));
		this._register(this.editPreferenceWidgetForMouseMove.onMouseOver(setting => this.onMouseOver(this.editPreferenceWidgetForMouseMove)));
783 784 785

		this._register(this.editor.onDidChangeCursorPosition(positionChangeEvent => this.onPositionChanged(positionChangeEvent)));
		this._register(this.editor.onMouseMove(mouseMoveEvent => this.onMouseMoved(mouseMoveEvent)));
S
Sandeep Somavarapu 已提交
786 787
	}

788
	public render(settingsGroups: ISettingsGroup[]): void {
789 790
		this.editPreferenceWidgetForCusorPosition.hide();
		this.editPreferenceWidgetForMouseMove.hide();
791
		this.settingsGroups = settingsGroups;
S
Sandeep Somavarapu 已提交
792

793 794
		const settings = this.getSettings(this.editor.getPosition().lineNumber);
		if (settings.length) {
795
			this.showEditPreferencesWidget(this.editPreferenceWidgetForCusorPosition, settings);
S
Sandeep Somavarapu 已提交
796 797 798
		}
	}

799 800 801 802
	private isDefaultSettings(): boolean {
		return this.masterSettingsModel instanceof DefaultSettingsEditorModel;
	}

803
	private onPositionChanged(positionChangeEvent: editorCommon.ICursorPositionChangedEvent) {
804
		this.editPreferenceWidgetForMouseMove.hide();
805 806
		const settings = this.getSettings(positionChangeEvent.position.lineNumber);
		if (settings.length) {
807
			this.showEditPreferencesWidget(this.editPreferenceWidgetForCusorPosition, settings);
808
		} else {
809
			this.editPreferenceWidgetForCusorPosition.hide();
810
		}
S
Sandeep Somavarapu 已提交
811 812
	}

813
	private onMouseMoved(mouseMoveEvent: IEditorMouseEvent): void {
S
#17292  
Sandeep Somavarapu 已提交
814 815 816
		const editPreferenceWidget = this.getEditPreferenceWidgetUnderMouse(mouseMoveEvent);
		if (editPreferenceWidget) {
			this.onMouseOver(editPreferenceWidget);
S
Sandeep Somavarapu 已提交
817 818
			return;
		}
819 820 821 822
		this.settingHighlighter.clear();
		this.toggleEditPreferencesForMouseMoveDelayer.trigger(() => this.toggleEidtPreferenceWidgetForMouseMove(mouseMoveEvent));
	}

S
#17292  
Sandeep Somavarapu 已提交
823 824 825
	private getEditPreferenceWidgetUnderMouse(mouseMoveEvent: IEditorMouseEvent): EditPreferenceWidget<ISetting> {
		if (mouseMoveEvent.event.target === this.editPreferenceWidgetForMouseMove.getDomNode()) {
			return this.editPreferenceWidgetForMouseMove;
S
Sandeep Somavarapu 已提交
826
		}
S
#17292  
Sandeep Somavarapu 已提交
827 828 829 830 831
		if (mouseMoveEvent.event.target === this.editPreferenceWidgetForCusorPosition.getDomNode()) {
			return this.editPreferenceWidgetForCusorPosition;
		}
		return null;
	}
S
Sandeep Somavarapu 已提交
832

833
	private toggleEidtPreferenceWidgetForMouseMove(mouseMoveEvent: IEditorMouseEvent): void {
834
		const settings = mouseMoveEvent.target.position ? this.getSettings(mouseMoveEvent.target.position.lineNumber) : null;
835 836
		if (settings && settings.length) {
			this.showEditPreferencesWidget(this.editPreferenceWidgetForMouseMove, settings);
837
		} else {
838
			this.editPreferenceWidgetForMouseMove.hide();
S
Sandeep Somavarapu 已提交
839 840 841
		}
	}

842 843 844
	private showEditPreferencesWidget(editPreferencesWidget: EditPreferenceWidget<ISetting>, settings: ISetting[]) {
		editPreferencesWidget.show(settings[0].valueRange.startLineNumber, settings);
		editPreferencesWidget.getDomNode().title = nls.localize('editTtile', "Edit");
S
Sandeep Somavarapu 已提交
845 846
	}

847 848 849 850
	private getSettings(lineNumber: number): ISetting[] {
		const configurationMap = this.getConfigurationsMap();
		return this.getSettingsAtLineNumber(lineNumber).filter(setting => {
			let jsonSchema: IJSONSchema = configurationMap[setting.key];
851
			return jsonSchema && (this.isDefaultSettings() || jsonSchema.type === 'boolean' || jsonSchema.enum);
852
		});
S
Sandeep Somavarapu 已提交
853 854
	}

855 856
	private getSettingsAtLineNumber(lineNumber: number): ISetting[] {
		const settings = [];
857
		for (const group of this.settingsGroups) {
858 859 860
			if (group.range.startLineNumber > lineNumber) {
				break;
			}
861 862 863
			if (lineNumber >= group.range.startLineNumber && lineNumber <= group.range.endLineNumber) {
				for (const section of group.sections) {
					for (const setting of section.settings) {
864 865 866 867 868
						if (setting.range.startLineNumber > lineNumber) {
							break;
						}
						if (lineNumber >= setting.range.startLineNumber && lineNumber <= setting.range.endLineNumber) {
							settings.push(setting);
869 870 871 872 873
						}
					}
				}
			}
		}
874 875 876
		return settings;
	}

877 878
	private onMouseOver(editPreferenceWidget: EditPreferenceWidget<ISetting>): void {
		this.settingHighlighter.highlight(editPreferenceWidget.preferences[0]);
879 880
	}

881 882
	private onEditSettingClicked(editPreferenceWidget: EditPreferenceWidget<ISetting>): void {
		const elementPosition = DOM.getDomNodePagePosition(editPreferenceWidget.getDomNode());
883
		const anchor = { x: elementPosition.left + elementPosition.width, y: elementPosition.top + elementPosition.height + 10 };
884
		const actions = this.getSettingsAtLineNumber(editPreferenceWidget.getLine()).length === 1 ? this.getActions(editPreferenceWidget.preferences[0], this.getConfigurationsMap()[editPreferenceWidget.preferences[0].key])
885
			: editPreferenceWidget.preferences.map(setting => new ContextSubMenu(setting.key, this.getActions(setting, this.getConfigurationsMap()[setting.key])));
886 887 888 889 890 891 892 893
		this.contextMenuService.showContextMenu({
			getAnchor: () => anchor,
			getActions: () => TPromise.wrap(actions)
		});
	}

	private getConfigurationsMap(): { [qualifiedKey: string]: IJSONSchema } {
		return Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties();
894 895 896
	}

	private getActions(setting: ISetting, jsonSchema: IJSONSchema): IAction[] {
S
Sandeep Somavarapu 已提交
897 898 899 900 901
		if (jsonSchema.type === 'boolean') {
			return [<IAction>{
				id: 'truthyValue',
				label: 'true',
				enabled: true,
902
				run: () => this.updateSetting(setting, true)
S
Sandeep Somavarapu 已提交
903 904 905 906
			}, <IAction>{
				id: 'falsyValue',
				label: 'false',
				enabled: true,
907
				run: () => this.updateSetting(setting, false)
S
Sandeep Somavarapu 已提交
908 909 910 911 912 913
			}];
		}
		if (jsonSchema.enum) {
			return jsonSchema.enum.map(value => {
				return <IAction>{
					id: value,
S
Sandeep Somavarapu 已提交
914
					label: JSON.stringify(value),
S
Sandeep Somavarapu 已提交
915
					enabled: true,
916
					run: () => this.updateSetting(setting, value)
S
Sandeep Somavarapu 已提交
917 918 919
				};
			});
		}
920
		return this.getDefaultActions(setting);
S
Sandeep Somavarapu 已提交
921
	}
922

923 924 925 926 927 928 929 930 931 932 933
	private getDefaultActions(setting: ISetting): IAction[] {
		const settingInOtherModel = this.otherSettingsModel.getSetting(setting.key);
		if (this.isDefaultSettings()) {
			return [<IAction>{
				id: 'setDefaultValue',
				label: settingInOtherModel ? nls.localize('replaceDefaultValue', "Replace in Settings") : nls.localize('copyDefaultValue', "Copy to Settings"),
				enabled: true,
				run: () => this.updateSetting(setting, setting.value)
			}];
		}
		return [];
S
Sandeep Somavarapu 已提交
934
	}
935

936
	private updateSetting(setting: ISetting, value: any): void {
937
		this._onUpdateSetting.fire({ setting, value });
938
	}
S
Sandeep Somavarapu 已提交
939 940
}

941 942 943 944 945 946 947 948 949 950 951
class SettingHighlighter extends Disposable {

	private fixedHighlighter: RangeHighlightDecorations;
	private volatileHighlighter: RangeHighlightDecorations;

	constructor(private editor: editorCommon.ICommonCodeEditor, @IInstantiationService instantiationService: IInstantiationService) {
		super();
		this.fixedHighlighter = this._register(instantiationService.createInstance(RangeHighlightDecorations));
		this.volatileHighlighter = this._register(instantiationService.createInstance(RangeHighlightDecorations));
	}

S
Sandeep Somavarapu 已提交
952
	highlight(setting: ISetting, fix: boolean = false) {
953 954 955 956 957
		this.volatileHighlighter.removeHighlightRange();
		this.fixedHighlighter.removeHighlightRange();

		const highlighter = fix ? this.fixedHighlighter : this.volatileHighlighter;
		highlighter.highlightRange({
S
Sandeep Somavarapu 已提交
958 959
			range: setting.valueRange,
			resource: this.editor.getModel().uri
960
		}, this.editor);
961 962

		this.editor.revealLinesInCenterIfOutsideViewport(setting.valueRange.startLineNumber, setting.valueRange.endLineNumber - 1);
963 964
	}

965
	clear(fix: boolean = false): void {
966
		this.volatileHighlighter.removeHighlightRange();
967 968
		if (fix) {
			this.fixedHighlighter.removeHighlightRange();
S
Sandeep Somavarapu 已提交
969
		}
970
	}
S
Sandeep Somavarapu 已提交
971 972
}

973
const DefaultSettingsEditorCommand = EditorCommand.bindToContribution<PreferencesEditorContribution>((editor: editorCommon.ICommonCodeEditor) => <PreferencesEditorContribution>editor.getContribution(DefaultSettingsEditorContribution.ID));
S
Sandeep Somavarapu 已提交
974 975 976 977 978

CommonEditorRegistry.registerEditorCommand(new DefaultSettingsEditorCommand({
	id: DEFAULT_EDITOR_COMMAND_COLLAPSE_ALL,
	precondition: ContextKeyExpr.and(CONTEXT_DEFAULT_SETTINGS_EDITOR),
	handler: x => (<DefaultSettingsRenderer>x.getPreferencesRenderer()).collapseAll()
979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
}));

class StartSearchDefaultSettingsCommand extends Command {

	public runCommand(accessor: ServicesAccessor, args: any): void {
		const defaultPreferencesEditor = this.getDefaultPreferencesEditor(accessor);
		if (defaultPreferencesEditor) {
			defaultPreferencesEditor.focus();
		}
	}

	private getDefaultPreferencesEditor(accessor: ServicesAccessor): DefaultPreferencesEditor {
		const activeEditor = accessor.get(IWorkbenchEditorService).getActiveEditor();
		if (activeEditor instanceof SideBySideEditor) {
			const detailsEditor = activeEditor.getDetailsEditor();
			if (detailsEditor instanceof DefaultPreferencesEditor) {
				return detailsEditor;
			}
		}
		return null;
	}
}

CommonEditorRegistry.registerEditorCommand(new StartSearchDefaultSettingsCommand({
	id: DEFAULT_EDITOR_COMMAND_FOCUS_SEARCH,
	precondition: ContextKeyExpr.and(CONTEXT_DEFAULT_SETTINGS_EDITOR),
	kbOpts: { primary: KeyMod.CtrlCmd | KeyCode.KEY_F }
S
Sandeep Somavarapu 已提交
1006
}));