simpleServices.ts 22.8 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

J
Johannes Rieken 已提交
7
import { Schemas } from 'vs/base/common/network';
E
Erich Gamma 已提交
8
import Severity from 'vs/base/common/severity';
9
import URI from 'vs/base/common/uri';
J
Johannes Rieken 已提交
10
import { TPromise } from 'vs/base/common/winjs.base';
A
Alex Dima 已提交
11
import { IConfigurationService, IConfigurationChangeEvent, IConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration';
12
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
13 14
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { ITextEditorService } from 'vs/editor/browser/services/textEditorService';
15
import { ICommandService, ICommand, ICommandEvent, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
16 17
import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
18
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
19
import { IKeybindingEvent, KeybindingSource, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';
20
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
21
import { IWorkspaceContextService, IWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
A
Alex Dima 已提交
22
import * as editorCommon from 'vs/editor/common/editorCommon';
23
import { ICodeEditor, IDiffEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser';
M
Matt Bierner 已提交
24
import { Event, Emitter } from 'vs/base/common/event';
S
Sandeep Somavarapu 已提交
25
import { Configuration, DefaultConfigurationModel, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
J
Johannes Rieken 已提交
26 27
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IProgressService, IProgressRunner } from 'vs/platform/progress/common/progress';
28
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
29
import { ITextModelService, ITextModelContentProvider, ITextEditorModel } from 'vs/editor/common/services/resolverService';
30
import { IDisposable, IReference, ImmortalReference, combinedDisposable } from 'vs/base/common/lifecycle';
31 32
import * as dom from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
A
Renames  
Alex Dima 已提交
33
import { KeybindingsRegistry, IKeybindingItem } from 'vs/platform/keybinding/common/keybindingsRegistry';
34
import { MenuId, IMenu, IMenuService } from 'vs/platform/actions/common/actions';
A
Alex Dima 已提交
35
import { Menu } from 'vs/platform/actions/common/menu';
36
import { ITelemetryService, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
37
import { ResolvedKeybinding, Keybinding, createKeybinding, SimpleKeybinding } from 'vs/base/common/keyCodes';
38
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
A
Alex Dima 已提交
39
import { OS } from 'vs/base/common/platform';
40
import { IRange, Range } from 'vs/editor/common/core/range';
A
Alex Dima 已提交
41
import { ITextModel } from 'vs/editor/common/model';
42
import { INotificationService, INotification, INotificationHandle, NoOpNotification, IPromptChoice } from 'vs/platform/notification/common/notification';
43
import { IConfirmation, IConfirmationResult, IDialogService, IDialogOptions } from 'vs/platform/dialogs/common/dialogs';
44
import { IPosition, Position as Pos } from 'vs/editor/common/core/position';
45
import { isEditorConfigurationKey, isDiffEditorConfigurationKey } from 'vs/editor/common/config/commonEditorConfig';
46 47 48 49 50
import { IBulkEditService, IBulkEditOptions, IBulkEditResult } from 'vs/editor/browser/services/bulkEditService';
import { WorkspaceEdit, isResourceTextEdit, TextEdit } from 'vs/editor/common/modes';
import { IModelService } from 'vs/editor/common/services/modelService';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { localize } from 'vs/nls';
E
Erich Gamma 已提交
51

52
export class SimpleEditor {
E
Erich Gamma 已提交
53

J
Johannes Rieken 已提交
54
	public _widget: editorCommon.IEditor;
E
Erich Gamma 已提交
55

J
Johannes Rieken 已提交
56
	constructor(editor: editorCommon.IEditor) {
E
Erich Gamma 已提交
57 58 59
		this._widget = editor;
	}

J
Johannes Rieken 已提交
60 61 62 63
	public getId(): string { return 'editor'; }
	public getControl(): editorCommon.IEditor { return this._widget; }
	public focus(): void { this._widget.focus(); }
	public isVisible(): boolean { return true; }
E
Erich Gamma 已提交
64

J
Johannes Rieken 已提交
65
	public withTypedEditor<T>(codeEditorCallback: (editor: ICodeEditor) => T, diffEditorCallback: (editor: IDiffEditor) => T): T {
66
		if (isCodeEditor(this._widget)) {
E
Erich Gamma 已提交
67
			// Single Editor
A
Alex Dima 已提交
68
			return codeEditorCallback(<ICodeEditor>this._widget);
E
Erich Gamma 已提交
69 70
		} else {
			// Diff Editor
A
Alex Dima 已提交
71
			return diffEditorCallback(<IDiffEditor>this._widget);
E
Erich Gamma 已提交
72 73 74 75
		}
	}
}

J
Johannes Rieken 已提交
76
export class SimpleModel implements ITextEditorModel {
E
Erich Gamma 已提交
77

A
Alex Dima 已提交
78
	private model: ITextModel;
M
Matt Bierner 已提交
79
	private readonly _onDispose: Emitter<void>;
E
Erich Gamma 已提交
80

A
Alex Dima 已提交
81
	constructor(model: ITextModel) {
E
Erich Gamma 已提交
82
		this.model = model;
83 84 85 86 87
		this._onDispose = new Emitter<void>();
	}

	public get onDispose(): Event<void> {
		return this._onDispose.event;
E
Erich Gamma 已提交
88 89
	}

90 91 92 93
	public load(): TPromise<SimpleModel> {
		return TPromise.as(this);
	}

A
Alex Dima 已提交
94
	public get textEditorModel(): ITextModel {
E
Erich Gamma 已提交
95 96
		return this.model;
	}
97 98 99 100

	public dispose(): void {
		this._onDispose.fire();
	}
E
Erich Gamma 已提交
101 102 103
}

export interface IOpenEditorDelegate {
J
Johannes Rieken 已提交
104
	(url: string): boolean;
E
Erich Gamma 已提交
105 106
}

107
export class SimpleEditorService implements ITextEditorService {
108
	public _serviceBrand: any;
E
Erich Gamma 已提交
109

J
Johannes Rieken 已提交
110 111
	private editor: SimpleEditor;
	private openEditorDelegate: IOpenEditorDelegate;
E
Erich Gamma 已提交
112 113 114 115 116

	constructor() {
		this.openEditorDelegate = null;
	}

J
Johannes Rieken 已提交
117
	public setEditor(editor: editorCommon.IEditor): void {
E
Erich Gamma 已提交
118 119 120
		this.editor = new SimpleEditor(editor);
	}

J
Johannes Rieken 已提交
121
	public setOpenEditorDelegate(openEditorDelegate: IOpenEditorDelegate): void {
E
Erich Gamma 已提交
122 123 124
		this.openEditorDelegate = openEditorDelegate;
	}

125
	public openTextEditor(typedData: IResourceInput, sideBySide?: boolean): TPromise<ICodeEditor> {
E
Erich Gamma 已提交
126 127 128 129 130 131 132 133 134
		return TPromise.as(this.editor.withTypedEditor(
			(editor) => this.doOpenEditor(editor, typedData),
			(diffEditor) => (
				this.doOpenEditor(diffEditor.getOriginalEditor(), typedData) ||
				this.doOpenEditor(diffEditor.getModifiedEditor(), typedData)
			)
		));
	}

135
	private doOpenEditor(editor: ICodeEditor, data: IResourceInput): ICodeEditor {
A
Alex Dima 已提交
136
		let model = this.findModel(editor, data);
E
Erich Gamma 已提交
137 138 139 140 141 142
		if (!model) {
			if (data.resource) {
				if (this.openEditorDelegate) {
					this.openEditorDelegate(data.resource.toString());
					return null;
				} else {
A
Alex Dima 已提交
143
					let schema = data.resource.scheme;
A
Alex Dima 已提交
144
					if (schema === Schemas.http || schema === Schemas.https) {
E
Erich Gamma 已提交
145
						// This is a fully qualified http or https URL
146
						dom.windowOpenNoOpener(data.resource.toString());
147
						return this.editor.getControl() as ICodeEditor;
E
Erich Gamma 已提交
148 149 150 151 152 153
					}
				}
			}
			return null;
		}

A
Alex Dima 已提交
154
		let selection = <IRange>data.options.selection;
E
Erich Gamma 已提交
155 156 157
		if (selection) {
			if (typeof selection.endLineNumber === 'number' && typeof selection.endColumn === 'number') {
				editor.setSelection(selection);
158
				editor.revealRangeInCenter(selection, editorCommon.ScrollType.Immediate);
E
Erich Gamma 已提交
159
			} else {
A
Alex Dima 已提交
160
				let pos = {
E
Erich Gamma 已提交
161 162 163 164
					lineNumber: selection.startLineNumber,
					column: selection.startColumn
				};
				editor.setPosition(pos);
165
				editor.revealPositionInCenter(pos, editorCommon.ScrollType.Immediate);
E
Erich Gamma 已提交
166 167 168
			}
		}

169
		return this.editor.getControl() as ICodeEditor;
E
Erich Gamma 已提交
170 171
	}

A
Alex Dima 已提交
172
	private findModel(editor: ICodeEditor, data: IResourceInput): ITextModel {
A
Alex Dima 已提交
173
		let model = editor.getModel();
J
Johannes Rieken 已提交
174
		if (model.uri.toString() !== data.resource.toString()) {
E
Erich Gamma 已提交
175 176 177 178 179 180 181
			return null;
		}

		return model;
	}
}

182
export class SimpleEditorModelResolverService implements ITextModelService {
183 184 185 186 187 188 189 190
	public _serviceBrand: any;

	private editor: SimpleEditor;

	public setEditor(editor: editorCommon.IEditor): void {
		this.editor = new SimpleEditor(editor);
	}

J
Joao Moreno 已提交
191
	public createModelReference(resource: URI): TPromise<IReference<ITextEditorModel>> {
A
Alex Dima 已提交
192
		let model: ITextModel;
193 194 195 196 197 198 199

		model = this.editor.withTypedEditor(
			(editor) => this.findModel(editor, resource),
			(diffEditor) => this.findModel(diffEditor.getOriginalEditor(), resource) || this.findModel(diffEditor.getModifiedEditor(), resource)
		);

		if (!model) {
J
Joao Moreno 已提交
200
			return TPromise.as(new ImmortalReference(null));
201 202
		}

J
Joao Moreno 已提交
203
		return TPromise.as(new ImmortalReference(new SimpleModel(model)));
204 205 206 207 208 209 210 211
	}

	public registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): IDisposable {
		return {
			dispose: function () { /* no op */ }
		};
	}

A
Alex Dima 已提交
212
	private findModel(editor: ICodeEditor, resource: URI): ITextModel {
213 214 215 216 217 218 219 220 221
		let model = editor.getModel();
		if (model.uri.toString() !== resource.toString()) {
			return null;
		}

		return model;
	}
}

222 223 224
export class SimpleProgressService implements IProgressService {
	_serviceBrand: any;

J
Johannes Rieken 已提交
225 226 227 228
	private static NULL_PROGRESS_RUNNER: IProgressRunner = {
		done: () => { },
		total: () => { },
		worked: () => { }
229 230 231 232 233 234 235 236 237 238 239 240 241
	};

	show(infinite: boolean, delay?: number): IProgressRunner;
	show(total: number, delay?: number): IProgressRunner;
	show(): IProgressRunner {
		return SimpleProgressService.NULL_PROGRESS_RUNNER;
	}

	showWhile(promise: TPromise<any>, delay?: number): TPromise<void> {
		return null;
	}
}

242
export class SimpleDialogService implements IDialogService {
243 244

	public _serviceBrand: any;
E
Erich Gamma 已提交
245

246 247 248 249 250 251 252 253 254 255
	public confirm(confirmation: IConfirmation): TPromise<IConfirmationResult> {
		return this.doConfirm(confirmation).then(confirmed => {
			return {
				confirmed,
				checkboxChecked: false // unsupported
			} as IConfirmationResult;
		});
	}

	private doConfirm(confirmation: IConfirmation): TPromise<boolean> {
A
Alex Dima 已提交
256
		let messageText = confirmation.message;
E
Erich Gamma 已提交
257 258 259 260
		if (confirmation.detail) {
			messageText = messageText + '\n\n' + confirmation.detail;
		}

261
		return TPromise.wrap(window.confirm(messageText));
E
Erich Gamma 已提交
262
	}
263

264
	public show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): TPromise<number> {
265 266
		return TPromise.as(0);
	}
A
Alex Dima 已提交
267 268
}

269 270 271 272
export class SimpleNotificationService implements INotificationService {

	public _serviceBrand: any;

273
	private static readonly NO_OP: INotificationHandle = new NoOpNotification();
274

B
Benjamin Pasero 已提交
275 276 277 278 279 280 281 282 283
	public info(message: string): INotificationHandle {
		return this.notify({ severity: Severity.Info, message });
	}

	public warn(message: string): INotificationHandle {
		return this.notify({ severity: Severity.Warning, message });
	}

	public error(error: string | Error): INotificationHandle {
284 285 286
		return this.notify({ severity: Severity.Error, message: error });
	}

287 288
	public notify(notification: INotification): INotificationHandle {
		switch (notification.severity) {
289
			case Severity.Error:
290
				console.error(notification.message);
291 292
				break;
			case Severity.Warning:
293
				console.warn(notification.message);
294 295
				break;
			default:
296
				console.log(notification.message);
297 298 299
				break;
		}

300
		return SimpleNotificationService.NO_OP;
301
	}
302

303 304
	public prompt(severity: Severity, message: string, choices: IPromptChoice[], onCancel?: () => void): INotificationHandle {
		return SimpleNotificationService.NO_OP;
305
	}
306 307
}

A
Alex Dima 已提交
308 309
export class StandaloneCommandService implements ICommandService {
	_serviceBrand: any;
310

A
Alex Dima 已提交
311
	private readonly _instantiationService: IInstantiationService;
312 313
	private _dynamicCommands: { [id: string]: ICommand; };

M
Matt Bierner 已提交
314
	private readonly _onWillExecuteCommand: Emitter<ICommandEvent> = new Emitter<ICommandEvent>();
315 316
	public readonly onWillExecuteCommand: Event<ICommandEvent> = this._onWillExecuteCommand.event;

A
Alex Dima 已提交
317 318
	constructor(instantiationService: IInstantiationService) {
		this._instantiationService = instantiationService;
319 320 321
		this._dynamicCommands = Object.create(null);
	}

J
Johannes Rieken 已提交
322 323
	public addCommand(command: ICommand): IDisposable {
		const { id } = command;
324
		this._dynamicCommands[id] = command;
325 326 327 328 329
		return {
			dispose: () => {
				delete this._dynamicCommands[id];
			}
		};
330 331
	}

A
Alex Dima 已提交
332 333 334
	public executeCommand<T>(id: string, ...args: any[]): TPromise<T> {
		const command = (CommandsRegistry.getCommand(id) || this._dynamicCommands[id]);
		if (!command) {
335
			return TPromise.wrapError<T>(new Error(`command '${id}' not found`));
A
Alex Dima 已提交
336 337 338
		}

		try {
339
			this._onWillExecuteCommand.fire({ commandId: id });
A
Alex Dima 已提交
340 341 342
			const result = this._instantiationService.invokeFunction.apply(this._instantiationService, [command.handler].concat(args));
			return TPromise.as(result);
		} catch (err) {
343
			return TPromise.wrapError<T>(err);
A
Alex Dima 已提交
344
		}
345 346 347
	}
}

348 349
export class StandaloneKeybindingService extends AbstractKeybindingService {
	private _cachedResolver: KeybindingResolver;
E
Erich Gamma 已提交
350 351
	private _dynamicKeybindings: IKeybindingItem[];

A
Alex Dima 已提交
352
	constructor(
353
		contextKeyService: IContextKeyService,
A
Alex Dima 已提交
354
		commandService: ICommandService,
355
		telemetryService: ITelemetryService,
356
		notificationService: INotificationService,
A
Alex Dima 已提交
357 358
		domNode: HTMLElement
	) {
359
		super(contextKeyService, commandService, telemetryService, notificationService);
360

361
		this._cachedResolver = null;
E
Erich Gamma 已提交
362
		this._dynamicKeybindings = [];
363

364
		this._register(dom.addDisposableListener(domNode, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
365
			let keyEvent = new StandardKeyboardEvent(e);
366
			let shouldPreventDefault = this._dispatch(keyEvent, keyEvent.target);
367 368 369 370
			if (shouldPreventDefault) {
				keyEvent.preventDefault();
			}
		}));
E
Erich Gamma 已提交
371 372
	}

373
	public addDynamicKeybinding(commandId: string, keybinding: number, handler: ICommandHandler, when: ContextKeyExpr): IDisposable {
374 375
		let toDispose: IDisposable[] = [];

E
Erich Gamma 已提交
376
		this._dynamicKeybindings.push({
A
Renames  
Alex Dima 已提交
377
			keybinding: createKeybinding(keybinding, OS),
E
Erich Gamma 已提交
378
			command: commandId,
379
			when: when,
E
Erich Gamma 已提交
380 381 382
			weight1: 1000,
			weight2: 0
		});
383

384 385 386 387 388 389 390 391 392 393 394 395 396
		toDispose.push({
			dispose: () => {
				for (let i = 0; i < this._dynamicKeybindings.length; i++) {
					let kb = this._dynamicKeybindings[i];
					if (kb.command === commandId) {
						this._dynamicKeybindings.splice(i, 1);
						this.updateResolver({ source: KeybindingSource.Default });
						return;
					}
				}
			}
		});

397 398
		let commandService = this._commandService;
		if (commandService instanceof StandaloneCommandService) {
J
Johannes Rieken 已提交
399 400
			toDispose.push(commandService.addCommand({
				id: commandId,
401
				handler: handler
402
			}));
403 404 405
		} else {
			throw new Error('Unknown command service!');
		}
C
Christof Marti 已提交
406
		this.updateResolver({ source: KeybindingSource.Default });
407

408
		return combinedDisposable(toDispose);
E
Erich Gamma 已提交
409 410
	}

411 412 413 414 415 416 417
	private updateResolver(event: IKeybindingEvent): void {
		this._cachedResolver = null;
		this._onDidUpdateKeybindings.fire(event);
	}

	protected _getResolver(): KeybindingResolver {
		if (!this._cachedResolver) {
418 419
			const defaults = this._toNormalizedKeybindingItems(KeybindingsRegistry.getDefaultKeybindings(), true);
			const overrides = this._toNormalizedKeybindingItems(this._dynamicKeybindings, false);
420
			this._cachedResolver = new KeybindingResolver(defaults, overrides);
421 422 423 424
		}
		return this._cachedResolver;
	}

425 426 427 428
	protected _documentHasFocus(): boolean {
		return document.hasFocus();
	}

429 430
	private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
		let result: ResolvedKeybindingItem[] = [], resultLen = 0;
431 432 433
		for (let i = 0, len = items.length; i < len; i++) {
			const item = items[i];
			const when = (item.when ? item.when.normalize() : null);
A
Alex Dima 已提交
434
			const keybinding = item.keybinding;
435

436 437 438 439 440 441 442 443 444
			if (!keybinding) {
				// This might be a removal keybinding item in user settings => accept it
				result[resultLen++] = new ResolvedKeybindingItem(null, item.command, item.commandArgs, when, isDefault);
			} else {
				const resolvedKeybindings = this.resolveKeybinding(keybinding);
				for (let j = 0; j < resolvedKeybindings.length; j++) {
					result[resultLen++] = new ResolvedKeybindingItem(resolvedKeybindings[j], item.command, item.commandArgs, when, isDefault);
				}
			}
445 446 447 448 449
		}

		return result;
	}

450 451
	public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[] {
		return [new USLayoutResolvedKeybinding(keybinding, OS)];
A
Alex Dima 已提交
452 453
	}

454 455 456 457 458 459 460 461
	public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding {
		let keybinding = new SimpleKeybinding(
			keyboardEvent.ctrlKey,
			keyboardEvent.shiftKey,
			keyboardEvent.altKey,
			keyboardEvent.metaKey,
			keyboardEvent.keyCode
		);
462
		return new USLayoutResolvedKeybinding(keybinding, OS);
463
	}
464 465 466 467

	public resolveUserBinding(userBinding: string): ResolvedKeybinding[] {
		return [];
	}
E
Erich Gamma 已提交
468 469
}

470 471 472 473 474 475 476
function isConfigurationOverrides(thing: any): thing is IConfigurationOverrides {
	return thing
		&& typeof thing === 'object'
		&& (!thing.overrideIdentifier || typeof thing.overrideIdentifier === 'string')
		&& (!thing.resource || thing.resource instanceof URI);
}

477
export class SimpleConfigurationService implements IConfigurationService {
478

479 480
	_serviceBrand: any;

481
	private _onDidChangeConfiguration = new Emitter<IConfigurationChangeEvent>();
482
	public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
483

484
	private _configuration: Configuration;
485

486
	constructor() {
487
		this._configuration = new Configuration(new DefaultConfigurationModel(), new ConfigurationModel());
488 489
	}

490
	private configuration(): Configuration {
491
		return this._configuration;
492 493
	}

494 495 496 497 498 499 500 501
	getValue<T>(): T;
	getValue<T>(section: string): T;
	getValue<T>(overrides: IConfigurationOverrides): T;
	getValue<T>(section: string, overrides: IConfigurationOverrides): T;
	getValue(arg1?: any, arg2?: any): any {
		const section = typeof arg1 === 'string' ? arg1 : void 0;
		const overrides = isConfigurationOverrides(arg1) ? arg1 : isConfigurationOverrides(arg2) ? arg2 : {};
		return this.configuration().getValue(section, overrides, null);
502 503
	}

504
	public updateValue(key: string, value: any, arg3?: any, arg4?: any): TPromise<void> {
505
		this.configuration().updateValue(key, value);
506
		return TPromise.as(null);
B
Benjamin Pasero 已提交
507
	}
B
Benjamin Pasero 已提交
508

S
Sandeep Somavarapu 已提交
509
	public inspect<C>(key: string, options: IConfigurationOverrides = {}): {
510 511 512 513 514 515
		default: C,
		user: C,
		workspace: C,
		workspaceFolder: C
		value: C,
	} {
516
		return this.configuration().inspect<C>(key, options, null);
B
Benjamin Pasero 已提交
517
	}
518

519
	public keys() {
S
Sandeep Somavarapu 已提交
520
		return this.configuration().keys(null);
521 522
	}

523 524
	public reloadConfiguration(): TPromise<void> {
		return TPromise.as(null);
525
	}
S
Sandeep Somavarapu 已提交
526

A
Alex Dima 已提交
527
	public getConfigurationData(): IConfigurationData {
S
Sandeep Somavarapu 已提交
528 529
		return null;
	}
530
}
A
Alex Dima 已提交
531

532 533 534 535
export class SimpleResourceConfigurationService implements ITextResourceConfigurationService {

	_serviceBrand: any;

536 537
	public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent>;
	private readonly _onDidChangeConfigurationEmitter = new Emitter();
538 539

	constructor(private configurationService: SimpleConfigurationService) {
540 541
		this.configurationService.onDidChangeConfiguration((e) => {
			this._onDidChangeConfigurationEmitter.fire(e);
542
		});
543 544
	}

545 546 547 548 549 550
	getValue<T>(resource: URI, section?: string): T;
	getValue<T>(resource: URI, position?: IPosition, section?: string): T;
	getValue<T>(resource: any, arg2?: any, arg3?: any) {
		const position: IPosition = Pos.isIPosition(arg2) ? arg2 : null;
		const section: string = position ? (typeof arg3 === 'string' ? arg3 : void 0) : (typeof arg2 === 'string' ? arg2 : void 0);
		return this.configurationService.getValue<T>(section);
551 552 553
	}
}

A
Alex Dima 已提交
554 555 556 557 558 559 560 561 562 563 564 565 566 567
export class SimpleMenuService implements IMenuService {

	_serviceBrand: any;

	private readonly _commandService: ICommandService;

	constructor(commandService: ICommandService) {
		this._commandService = commandService;
	}

	public createMenu(id: MenuId, contextKeyService: IContextKeyService): IMenu {
		return new Menu(id, TPromise.as(true), this._commandService, contextKeyService);
	}
}
568 569 570 571 572 573 574

export class StandaloneTelemetryService implements ITelemetryService {
	_serviceBrand: void;

	public isOptedIn = false;

	public publicLog(eventName: string, data?: any): TPromise<void> {
575
		return TPromise.wrap<void>(null);
576 577 578 579 580 581
	}

	public getTelemetryInfo(): TPromise<ITelemetryInfo> {
		return null;
	}
}
582 583 584 585 586

export class SimpleWorkspaceContextService implements IWorkspaceContextService {

	public _serviceBrand: any;

587 588
	private static SCHEME: 'inmemory';

S
Sandeep Somavarapu 已提交
589 590 591
	private readonly _onDidChangeWorkspaceName: Emitter<void> = new Emitter<void>();
	public readonly onDidChangeWorkspaceName: Event<void> = this._onDidChangeWorkspaceName.event;

592 593
	private readonly _onDidChangeWorkspaceFolders: Emitter<IWorkspaceFoldersChangeEvent> = new Emitter<IWorkspaceFoldersChangeEvent>();
	public readonly onDidChangeWorkspaceFolders: Event<IWorkspaceFoldersChangeEvent> = this._onDidChangeWorkspaceFolders.event;
594 595 596

	private readonly _onDidChangeWorkbenchState: Emitter<WorkbenchState> = new Emitter<WorkbenchState>();
	public readonly onDidChangeWorkbenchState: Event<WorkbenchState> = this._onDidChangeWorkbenchState.event;
597

598
	private readonly workspace: IWorkspace;
599

600
	constructor() {
601
		const resource = URI.from({ scheme: SimpleWorkspaceContextService.SCHEME, authority: 'model', path: '/' });
602
		this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })], name: resource.fsPath };
603 604
	}

B
Benjamin Pasero 已提交
605
	public getWorkspace(): IWorkspace {
606
		return this.workspace;
607 608
	}

609
	public getWorkbenchState(): WorkbenchState {
610 611
		if (this.workspace) {
			if (this.workspace.configuration) {
612
				return WorkbenchState.WORKSPACE;
613
			}
614
			return WorkbenchState.FOLDER;
615
		}
616
		return WorkbenchState.EMPTY;
617 618
	}

S
Sandeep Somavarapu 已提交
619
	public getWorkspaceFolder(resource: URI): IWorkspaceFolder {
S
Sandeep Somavarapu 已提交
620
		return resource && resource.scheme === SimpleWorkspaceContextService.SCHEME ? this.workspace.folders[0] : void 0;
621 622
	}

623
	public isInsideWorkspace(resource: URI): boolean {
624
		return resource && resource.scheme === SimpleWorkspaceContextService.SCHEME;
625 626
	}

627 628 629
	public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean {
		return true;
	}
630
}
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647

export function applyConfigurationValues(configurationService: IConfigurationService, source: any, isDiffEditor: boolean): void {
	if (!source) {
		return;
	}
	if (!(configurationService instanceof SimpleConfigurationService)) {
		return;
	}
	Object.keys(source).forEach((key) => {
		if (isEditorConfigurationKey(key)) {
			configurationService.updateValue(`editor.${key}`, source[key]);
		}
		if (isDiffEditor && isDiffEditorConfigurationKey(key)) {
			configurationService.updateValue(`diffEditor.${key}`, source[key]);
		}
	});
}
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688

export class SimpleBulkEditService implements IBulkEditService {
	_serviceBrand: any;

	constructor(private readonly _modelService: IModelService) {
		//
	}

	apply(workspaceEdit: WorkspaceEdit, options: IBulkEditOptions): TPromise<IBulkEditResult> {

		let edits = new Map<ITextModel, TextEdit[]>();

		for (let edit of workspaceEdit.edits) {
			if (!isResourceTextEdit(edit)) {
				return TPromise.wrapError(new Error('bad edit - only text edits are supported'));
			}
			let model = this._modelService.getModel(edit.resource);
			if (!model) {
				return TPromise.wrapError(new Error('bad edit - model not found'));
			}
			let array = edits.get(model);
			if (!array) {
				array = [];
			}
			edits.set(model, array.concat(edit.edits));
		}

		let totalEdits = 0;
		let totalFiles = 0;
		edits.forEach((edits, model) => {
			model.applyEdits(edits.map(edit => EditOperation.replaceMove(Range.lift(edit.range), edit.text)));
			totalFiles += 1;
			totalEdits += edits.length;
		});

		return TPromise.as({
			selection: undefined,
			ariaSummary: localize('summary', 'Made {0} edits in {1} files', totalEdits, totalFiles)
		});
	}
}