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

A
Alex Dima 已提交
6 7 8 9 10 11
import { localize } from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Emitter, Event } from 'vs/base/common/event';
import { Keybinding, ResolvedKeybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
import { IDisposable, IReference, ImmortalReference, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle';
12
import { OS, isLinux, isMacintosh } from 'vs/base/common/platform';
E
Erich Gamma 已提交
13
import Severity from 'vs/base/common/severity';
14
import { URI } from 'vs/base/common/uri';
15
import { ICodeEditor, IDiffEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser';
A
Alex Dima 已提交
16 17 18 19
import { IBulkEditOptions, IBulkEditResult, IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
import { isDiffEditorConfigurationKey, isEditorConfigurationKey } from 'vs/editor/common/config/commonEditorConfig';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { IPosition, Position as Pos } from 'vs/editor/common/core/position';
20
import { Range } from 'vs/editor/common/core/range';
A
Alex Dima 已提交
21
import * as editorCommon from 'vs/editor/common/editorCommon';
A
Alex Dima 已提交
22
import { ITextModel } from 'vs/editor/common/model';
A
Alex Dima 已提交
23
import { TextEdit, WorkspaceEdit, isResourceTextEdit } from 'vs/editor/common/modes';
24
import { IModelService } from 'vs/editor/common/services/modelService';
25
import { IResolvedTextEditorModel, ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService';
A
Alex Dima 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38
import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
import { CommandsRegistry, ICommand, ICommandEvent, ICommandHandler, ICommandService } from 'vs/platform/commands/common/commands';
import { IConfigurationChangeEvent, IConfigurationData, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Configuration, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfirmation, IConfirmationResult, IDialogOptions, IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { IKeybindingEvent, IKeyboardEvent, KeybindingSource } from 'vs/platform/keybinding/common/keybinding';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
import { IKeybindingItem, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
39
import { ILabelService, ResourceLabelFormatter } from 'vs/platform/label/common/label';
A
Alex Dima 已提交
40 41 42 43 44
import { INotification, INotificationHandle, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification } from 'vs/platform/notification/common/notification';
import { IProgressRunner, IProgressService } from 'vs/platform/progress/common/progress';
import { ITelemetryInfo, ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkbenchState, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
45
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
46
import { ILayoutService, IDimension } from 'vs/platform/layout/browser/layoutService';
E
Erich Gamma 已提交
47

48
export class SimpleModel implements IResolvedTextEditorModel {
E
Erich Gamma 已提交
49

50
	private readonly model: ITextModel;
M
Matt Bierner 已提交
51
	private readonly _onDispose: Emitter<void>;
E
Erich Gamma 已提交
52

A
Alex Dima 已提交
53
	constructor(model: ITextModel) {
E
Erich Gamma 已提交
54
		this.model = model;
55 56 57 58 59
		this._onDispose = new Emitter<void>();
	}

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

J
Johannes Rieken 已提交
62
	public load(): Promise<SimpleModel> {
63
		return Promise.resolve(this);
64 65
	}

A
Alex Dima 已提交
66
	public get textEditorModel(): ITextModel {
E
Erich Gamma 已提交
67 68
		return this.model;
	}
69

70 71 72 73
	public isReadonly(): boolean {
		return false;
	}

74 75 76
	public dispose(): void {
		this._onDispose.fire();
	}
E
Erich Gamma 已提交
77 78 79
}

export interface IOpenEditorDelegate {
J
Johannes Rieken 已提交
80
	(url: string): boolean;
E
Erich Gamma 已提交
81 82
}

B
Benjamin Pasero 已提交
83 84 85 86 87 88 89 90 91 92
function withTypedEditor<T>(widget: editorCommon.IEditor, codeEditorCallback: (editor: ICodeEditor) => T, diffEditorCallback: (editor: IDiffEditor) => T): T {
	if (isCodeEditor(widget)) {
		// Single Editor
		return codeEditorCallback(<ICodeEditor>widget);
	} else {
		// Diff Editor
		return diffEditorCallback(<IDiffEditor>widget);
	}
}

93
export class SimpleEditorModelResolverService implements ITextModelService {
94 95
	public _serviceBrand: any;

B
Benjamin Pasero 已提交
96
	private editor: editorCommon.IEditor;
97 98

	public setEditor(editor: editorCommon.IEditor): void {
B
Benjamin Pasero 已提交
99
		this.editor = editor;
100 101
	}

102
	public createModelReference(resource: URI): Promise<IReference<IResolvedTextEditorModel>> {
A
Alex Dima 已提交
103
		let model: ITextModel | null = withTypedEditor(this.editor,
104 105 106 107 108
			(editor) => this.findModel(editor, resource),
			(diffEditor) => this.findModel(diffEditor.getOriginalEditor(), resource) || this.findModel(diffEditor.getModifiedEditor(), resource)
		);

		if (!model) {
A
Alex Dima 已提交
109
			return Promise.reject(new Error(`Model not found`));
110 111
		}

112
		return Promise.resolve(new ImmortalReference(new SimpleModel(model)));
113 114 115 116 117 118 119 120
	}

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

121 122 123 124
	public hasTextModelContentProvider(scheme: string): boolean {
		return false;
	}

A
Alex Dima 已提交
125
	private findModel(editor: ICodeEditor, resource: URI): ITextModel | null {
126
		let model = editor.getModel();
A
Alex Dima 已提交
127
		if (model && model.uri.toString() !== resource.toString()) {
128 129 130 131 132 133 134
			return null;
		}

		return model;
	}
}

135 136 137
export class SimpleProgressService implements IProgressService {
	_serviceBrand: any;

J
Johannes Rieken 已提交
138 139 140 141
	private static NULL_PROGRESS_RUNNER: IProgressRunner = {
		done: () => { },
		total: () => { },
		worked: () => { }
142 143
	};

144
	show(infinite: true, delay?: number): IProgressRunner;
145 146 147 148 149
	show(total: number, delay?: number): IProgressRunner;
	show(): IProgressRunner {
		return SimpleProgressService.NULL_PROGRESS_RUNNER;
	}

J
Johannes Rieken 已提交
150
	showWhile(promise: Promise<any>, delay?: number): Promise<void> {
R
Rob Lourens 已提交
151
		return Promise.resolve(undefined);
152 153 154
	}
}

155
export class SimpleDialogService implements IDialogService {
156 157

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

J
Johannes Rieken 已提交
159
	public confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {
160 161 162 163 164 165 166 167
		return this.doConfirm(confirmation).then(confirmed => {
			return {
				confirmed,
				checkboxChecked: false // unsupported
			} as IConfirmationResult;
		});
	}

J
Johannes Rieken 已提交
168
	private doConfirm(confirmation: IConfirmation): Promise<boolean> {
A
Alex Dima 已提交
169
		let messageText = confirmation.message;
E
Erich Gamma 已提交
170 171 172 173
		if (confirmation.detail) {
			messageText = messageText + '\n\n' + confirmation.detail;
		}

A
Alex Dima 已提交
174
		return Promise.resolve(window.confirm(messageText));
E
Erich Gamma 已提交
175
	}
176

J
Johannes Rieken 已提交
177
	public show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise<number> {
A
Alex Dima 已提交
178
		return Promise.resolve(0);
179
	}
A
Alex Dima 已提交
180 181
}

182 183 184 185
export class SimpleNotificationService implements INotificationService {

	public _serviceBrand: any;

186
	private static readonly NO_OP: INotificationHandle = new NoOpNotification();
187

B
Benjamin Pasero 已提交
188 189 190 191 192 193 194 195 196
	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 {
197 198 199
		return this.notify({ severity: Severity.Error, message: error });
	}

200 201
	public notify(notification: INotification): INotificationHandle {
		switch (notification.severity) {
202
			case Severity.Error:
203
				console.error(notification.message);
204 205
				break;
			case Severity.Warning:
206
				console.warn(notification.message);
207 208
				break;
			default:
209
				console.log(notification.message);
210 211 212
				break;
		}

213
		return SimpleNotificationService.NO_OP;
214
	}
215

B
Benjamin Pasero 已提交
216
	public prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle {
217
		return SimpleNotificationService.NO_OP;
218
	}
219 220
}

221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
export class BrowserAccessibilityService implements IAccessibilityService {
	_serviceBrand: any;

	private _accessibilitySupport = AccessibilitySupport.Unknown;
	private readonly _onDidChangeAccessibilitySupport = new Emitter<void>();
	readonly onDidChangeAccessibilitySupport: Event<void> = this._onDidChangeAccessibilitySupport.event;

	alwaysUnderlineAccessKeys(): Promise<boolean> {
		return Promise.resolve(false);
	}

	setAccessibilitySupport(accessibilitySupport: AccessibilitySupport): void {
		if (this._accessibilitySupport === accessibilitySupport) {
			return;
		}

		this._accessibilitySupport = accessibilitySupport;
		this._onDidChangeAccessibilitySupport.fire();
	}

	getAccessibilitySupport(): AccessibilitySupport {
		return this._accessibilitySupport;
	}
}

A
Alex Dima 已提交
246 247
export class StandaloneCommandService implements ICommandService {
	_serviceBrand: any;
248

A
Alex Dima 已提交
249
	private readonly _instantiationService: IInstantiationService;
250
	private readonly _dynamicCommands: { [id: string]: ICommand; };
251

252
	private readonly _onWillExecuteCommand = new Emitter<ICommandEvent>();
253 254
	public readonly onWillExecuteCommand: Event<ICommandEvent> = this._onWillExecuteCommand.event;

A
Alex Dima 已提交
255 256
	constructor(instantiationService: IInstantiationService) {
		this._instantiationService = instantiationService;
257 258 259
		this._dynamicCommands = Object.create(null);
	}

J
Johannes Rieken 已提交
260 261
	public addCommand(command: ICommand): IDisposable {
		const { id } = command;
262
		this._dynamicCommands[id] = command;
263 264 265
		return toDisposable(() => {
			delete this._dynamicCommands[id];
		});
266 267
	}

268
	public executeCommand<T>(id: string, ...args: any[]): Promise<T> {
A
Alex Dima 已提交
269 270
		const command = (CommandsRegistry.getCommand(id) || this._dynamicCommands[id]);
		if (!command) {
271
			return Promise.reject(new Error(`command '${id}' not found`));
A
Alex Dima 已提交
272 273 274
		}

		try {
275
			this._onWillExecuteCommand.fire({ commandId: id });
276
			const result = this._instantiationService.invokeFunction.apply(this._instantiationService, [command.handler, ...args]) as T;
277
			return Promise.resolve(result);
A
Alex Dima 已提交
278
		} catch (err) {
279
			return Promise.reject(err);
A
Alex Dima 已提交
280
		}
281 282 283
	}
}

284
export class StandaloneKeybindingService extends AbstractKeybindingService {
A
Alex Dima 已提交
285
	private _cachedResolver: KeybindingResolver | null;
286
	private readonly _dynamicKeybindings: IKeybindingItem[];
E
Erich Gamma 已提交
287

A
Alex Dima 已提交
288
	constructor(
289
		contextKeyService: IContextKeyService,
A
Alex Dima 已提交
290
		commandService: ICommandService,
291
		telemetryService: ITelemetryService,
292
		notificationService: INotificationService,
A
Alex Dima 已提交
293 294
		domNode: HTMLElement
	) {
295
		super(contextKeyService, commandService, telemetryService, notificationService);
296

297
		this._cachedResolver = null;
E
Erich Gamma 已提交
298
		this._dynamicKeybindings = [];
299

300
		this._register(dom.addDisposableListener(domNode, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
301
			let keyEvent = new StandardKeyboardEvent(e);
302
			let shouldPreventDefault = this._dispatch(keyEvent, keyEvent.target);
303 304 305 306
			if (shouldPreventDefault) {
				keyEvent.preventDefault();
			}
		}));
E
Erich Gamma 已提交
307 308
	}

A
Alex Dima 已提交
309 310 311 312 313 314
	public addDynamicKeybinding(commandId: string, _keybinding: number, handler: ICommandHandler, when: ContextKeyExpr | null): IDisposable {
		const keybinding = createKeybinding(_keybinding, OS);
		if (!keybinding) {
			throw new Error(`Invalid keybinding`);
		}

315 316
		let toDispose: IDisposable[] = [];

E
Erich Gamma 已提交
317
		this._dynamicKeybindings.push({
A
Alex Dima 已提交
318
			keybinding: keybinding,
E
Erich Gamma 已提交
319
			command: commandId,
320
			when: when,
E
Erich Gamma 已提交
321 322 323
			weight1: 1000,
			weight2: 0
		});
324

325 326 327 328 329 330 331
		toDispose.push(toDisposable(() => {
			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;
332 333
				}
			}
334
		}));
335

336 337
		let commandService = this._commandService;
		if (commandService instanceof StandaloneCommandService) {
J
Johannes Rieken 已提交
338 339
			toDispose.push(commandService.addCommand({
				id: commandId,
340
				handler: handler
341
			}));
342 343 344
		} else {
			throw new Error('Unknown command service!');
		}
C
Christof Marti 已提交
345
		this.updateResolver({ source: KeybindingSource.Default });
346

347
		return combinedDisposable(toDispose);
E
Erich Gamma 已提交
348 349
	}

350 351 352 353 354 355 356
	private updateResolver(event: IKeybindingEvent): void {
		this._cachedResolver = null;
		this._onDidUpdateKeybindings.fire(event);
	}

	protected _getResolver(): KeybindingResolver {
		if (!this._cachedResolver) {
357 358
			const defaults = this._toNormalizedKeybindingItems(KeybindingsRegistry.getDefaultKeybindings(), true);
			const overrides = this._toNormalizedKeybindingItems(this._dynamicKeybindings, false);
359
			this._cachedResolver = new KeybindingResolver(defaults, overrides);
360 361 362 363
		}
		return this._cachedResolver;
	}

364 365 366 367
	protected _documentHasFocus(): boolean {
		return document.hasFocus();
	}

368 369
	private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
		let result: ResolvedKeybindingItem[] = [], resultLen = 0;
370
		for (const item of items) {
371
			const when = (item.when ? item.when.normalize() : null);
A
Alex Dima 已提交
372
			const keybinding = item.keybinding;
373

374 375 376 377 378
			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);
379 380
				for (const resolvedKeybinding of resolvedKeybindings) {
					result[resultLen++] = new ResolvedKeybindingItem(resolvedKeybinding, item.command, item.commandArgs, when, isDefault);
381 382
				}
			}
383 384 385 386 387
		}

		return result;
	}

388 389
	public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[] {
		return [new USLayoutResolvedKeybinding(keybinding, OS)];
A
Alex Dima 已提交
390 391
	}

392 393 394 395 396 397 398
	public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding {
		let keybinding = new SimpleKeybinding(
			keyboardEvent.ctrlKey,
			keyboardEvent.shiftKey,
			keyboardEvent.altKey,
			keyboardEvent.metaKey,
			keyboardEvent.keyCode
399
		).toChord();
400
		return new USLayoutResolvedKeybinding(keybinding, OS);
401
	}
402 403 404 405

	public resolveUserBinding(userBinding: string): ResolvedKeybinding[] {
		return [];
	}
406 407 408 409

	public _dumpDebugInfo(): string {
		return '';
	}
E
Erich Gamma 已提交
410 411
}

412 413 414 415 416 417 418
function isConfigurationOverrides(thing: any): thing is IConfigurationOverrides {
	return thing
		&& typeof thing === 'object'
		&& (!thing.overrideIdentifier || typeof thing.overrideIdentifier === 'string')
		&& (!thing.resource || thing.resource instanceof URI);
}

419
export class SimpleConfigurationService implements IConfigurationService {
420

421 422
	_serviceBrand: any;

423
	private _onDidChangeConfiguration = new Emitter<IConfigurationChangeEvent>();
424
	public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
425

426
	private readonly _configuration: Configuration;
427

428
	constructor() {
429
		this._configuration = new Configuration(new DefaultConfigurationModel(), new ConfigurationModel());
430 431
	}

432
	private configuration(): Configuration {
433
		return this._configuration;
434 435
	}

436 437 438 439 440
	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 {
R
Rob Lourens 已提交
441
		const section = typeof arg1 === 'string' ? arg1 : undefined;
442
		const overrides = isConfigurationOverrides(arg1) ? arg1 : isConfigurationOverrides(arg2) ? arg2 : {};
443
		return this.configuration().getValue(section, overrides, undefined);
444 445
	}

S
Sandeep Somavarapu 已提交
446
	public updateValue(key: string, value: any, arg3?: any, arg4?: any): Promise<void> {
447
		this.configuration().updateValue(key, value);
A
Alex Dima 已提交
448
		return Promise.resolve();
B
Benjamin Pasero 已提交
449
	}
B
Benjamin Pasero 已提交
450

S
Sandeep Somavarapu 已提交
451
	public inspect<C>(key: string, options: IConfigurationOverrides = {}): {
452 453
		default: C,
		user: C,
M
Matt Bierner 已提交
454 455
		workspace?: C,
		workspaceFolder?: C
456 457
		value: C,
	} {
458
		return this.configuration().inspect<C>(key, options, undefined);
B
Benjamin Pasero 已提交
459
	}
460

461
	public keys() {
462
		return this.configuration().keys(undefined);
463 464
	}

S
Sandeep Somavarapu 已提交
465
	public reloadConfiguration(): Promise<void> {
R
Rob Lourens 已提交
466
		return Promise.resolve(undefined);
467
	}
S
Sandeep Somavarapu 已提交
468

A
Alex Dima 已提交
469
	public getConfigurationData(): IConfigurationData | null {
S
Sandeep Somavarapu 已提交
470 471
		return null;
	}
472
}
A
Alex Dima 已提交
473

474 475 476 477
export class SimpleResourceConfigurationService implements ITextResourceConfigurationService {

	_serviceBrand: any;

478 479
	public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent>;
	private readonly _onDidChangeConfigurationEmitter = new Emitter();
480

481
	constructor(private readonly configurationService: SimpleConfigurationService) {
482 483
		this.configurationService.onDidChangeConfiguration((e) => {
			this._onDidChangeConfigurationEmitter.fire(e);
484
		});
485 486
	}

487 488 489
	getValue<T>(resource: URI, section?: string): T;
	getValue<T>(resource: URI, position?: IPosition, section?: string): T;
	getValue<T>(resource: any, arg2?: any, arg3?: any) {
A
Alex Dima 已提交
490
		const position: IPosition | null = Pos.isIPosition(arg2) ? arg2 : null;
R
Rob Lourens 已提交
491
		const section: string | undefined = position ? (typeof arg3 === 'string' ? arg3 : undefined) : (typeof arg2 === 'string' ? arg2 : undefined);
A
Alex Dima 已提交
492 493 494
		if (typeof section === 'undefined') {
			return this.configurationService.getValue<T>();
		}
495
		return this.configurationService.getValue<T>(section);
496 497 498
	}
}

S
Sandeep Somavarapu 已提交
499 500 501 502 503
export class SimpleResourcePropertiesService implements ITextResourcePropertiesService {

	_serviceBrand: any;

	constructor(
504
		@IConfigurationService private readonly configurationService: IConfigurationService,
S
Sandeep Somavarapu 已提交
505 506 507 508 509 510 511 512 513 514 515 516 517 518
	) {
	}

	getEOL(resource: URI): string {
		const filesConfiguration = this.configurationService.getValue<{ eol: string }>('files');
		if (filesConfiguration && filesConfiguration.eol) {
			if (filesConfiguration.eol !== 'auto') {
				return filesConfiguration.eol;
			}
		}
		return (isLinux || isMacintosh) ? '\n' : '\r\n';
	}
}

519 520 521 522 523
export class StandaloneTelemetryService implements ITelemetryService {
	_serviceBrand: void;

	public isOptedIn = false;

524
	public publicLog(eventName: string, data?: any): Promise<void> {
R
Rob Lourens 已提交
525
		return Promise.resolve(undefined);
526 527
	}

528
	public getTelemetryInfo(): Promise<ITelemetryInfo> {
A
Alex Dima 已提交
529
		throw new Error(`Not available`);
530 531
	}
}
532 533 534 535 536

export class SimpleWorkspaceContextService implements IWorkspaceContextService {

	public _serviceBrand: any;

537
	private static SCHEME = 'inmemory';
538

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

542
	private readonly _onDidChangeWorkspaceFolders = new Emitter<IWorkspaceFoldersChangeEvent>();
543
	public readonly onDidChangeWorkspaceFolders: Event<IWorkspaceFoldersChangeEvent> = this._onDidChangeWorkspaceFolders.event;
544

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

548
	private readonly workspace: IWorkspace;
549

550
	constructor() {
551
		const resource = URI.from({ scheme: SimpleWorkspaceContextService.SCHEME, authority: 'model', path: '/' });
I
isidor 已提交
552
		this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [new WorkspaceFolder({ uri: resource, name: '', index: 0 })] };
553 554
	}

555 556 557 558
	getCompleteWorkspace(): Promise<IWorkspace> {
		return Promise.resolve(this.getWorkspace());
	}

B
Benjamin Pasero 已提交
559
	public getWorkspace(): IWorkspace {
560
		return this.workspace;
561 562
	}

563
	public getWorkbenchState(): WorkbenchState {
564 565
		if (this.workspace) {
			if (this.workspace.configuration) {
566
				return WorkbenchState.WORKSPACE;
567
			}
568
			return WorkbenchState.FOLDER;
569
		}
570
		return WorkbenchState.EMPTY;
571 572
	}

A
Alex Dima 已提交
573 574
	public getWorkspaceFolder(resource: URI): IWorkspaceFolder | null {
		return resource && resource.scheme === SimpleWorkspaceContextService.SCHEME ? this.workspace.folders[0] : null;
575 576
	}

577
	public isInsideWorkspace(resource: URI): boolean {
578
		return resource && resource.scheme === SimpleWorkspaceContextService.SCHEME;
579 580
	}

581
	public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean {
582 583
		return true;
	}
584
}
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601

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]);
		}
	});
}
602 603 604 605 606 607 608 609

export class SimpleBulkEditService implements IBulkEditService {
	_serviceBrand: any;

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

M
Matt Bierner 已提交
610
	apply(workspaceEdit: WorkspaceEdit, options?: IBulkEditOptions): Promise<IBulkEditResult> {
611 612 613

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

A
Alex Dima 已提交
614 615 616 617 618 619 620 621 622 623 624 625 626 627
		if (workspaceEdit.edits) {
			for (let edit of workspaceEdit.edits) {
				if (!isResourceTextEdit(edit)) {
					return Promise.reject(new Error('bad edit - only text edits are supported'));
				}
				let model = this._modelService.getModel(edit.resource);
				if (!model) {
					return Promise.reject(new Error('bad edit - model not found'));
				}
				let array = edits.get(model);
				if (!array) {
					array = [];
				}
				edits.set(model, array.concat(edit.edits));
628 629 630 631 632 633 634 635 636 637 638
			}
		}

		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;
		});

639
		return Promise.resolve({
640 641 642 643 644
			selection: undefined,
			ariaSummary: localize('summary', 'Made {0} edits in {1} files', totalEdits, totalFiles)
		});
	}
}
A
Alex Dima 已提交
645

I
isidor 已提交
646
export class SimpleUriLabelService implements ILabelService {
A
Alex Dima 已提交
647 648
	_serviceBrand: any;

649
	private readonly _onDidRegisterFormatter = new Emitter<void>();
650
	public readonly onDidChangeFormatters: Event<void> = this._onDidRegisterFormatter.event;
A
Alex Dima 已提交
651

652
	public getUriLabel(resource: URI, options?: { relative?: boolean, forceNoTildify?: boolean }): string {
A
Alex Dima 已提交
653 654 655 656 657 658
		if (resource.scheme === 'file') {
			return resource.fsPath;
		}
		return resource.path;
	}

I
isidor 已提交
659 660
	public getWorkspaceLabel(workspace: IWorkspaceIdentifier | URI | IWorkspace, options?: { verbose: boolean; }): string {
		return '';
661 662
	}

663 664 665 666
	public getSeparator(scheme: string, authority?: string): '/' | '\\' {
		return '/';
	}

667
	public registerFormatter(formatter: ResourceLabelFormatter): IDisposable {
A
Alex Dima 已提交
668 669
		throw new Error('Not implemented');
	}
I
isidor 已提交
670 671 672 673

	public getHostLabel(): string {
		return '';
	}
A
Alex Dima 已提交
674
}
675 676 677 678 679 680 681 682 683 684 685 686 687 688

export class SimpleLayoutService implements ILayoutService {
	_serviceBrand: any;

	public onLayout = Event.None;

	private _dimension: IDimension;
	get dimension(): IDimension {
		if (!this._dimension) {
			this._dimension = dom.getClientArea(window.document.body);
		}

		return this._dimension;
	}
689 690 691 692 693 694

	get container(): HTMLElement {
		return this._container;
	}

	constructor(private _container: HTMLElement) { }
695
}