mainThreadSCM.ts 9.8 KB
Newer Older
J
Joao Moreno 已提交
1 2 3 4
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
5

J
Joao Moreno 已提交
6 7
'use strict';

J
Joao Moreno 已提交
8 9
import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri';
J
Joao Moreno 已提交
10
import Event, { Emitter } from 'vs/base/common/event';
J
Joao Moreno 已提交
11
import { assign } from 'vs/base/common/objects';
J
Joao Moreno 已提交
12 13
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations } from 'vs/workbench/services/scm/common/scm';
J
Joao Moreno 已提交
14
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
J
Joao Moreno 已提交
15
import { ICommandService } from 'vs/platform/commands/common/commands';
16
import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResource, SCMGroupFeatures, MainContext, IExtHostContext } from '../node/extHost.protocol';
17
import { Command } from 'vs/editor/common/modes';
18
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
J
Joao Moreno 已提交
19

20 21 22 23 24 25 26 27
class MainThreadSCMResourceGroup implements ISCMResourceGroup {

	constructor(
		private sourceControlHandle: number,
		private handle: number,
		public provider: ISCMProvider,
		public features: SCMGroupFeatures,
		public label: string,
28
		public id: string,
29 30 31 32 33 34 35 36 37 38
		public resources: ISCMResource[]
	) { }

	toJSON(): any {
		return {
			$mid: 4,
			sourceControlHandle: this.sourceControlHandle,
			groupHandle: this.handle
		};
	}
J
Joao Moreno 已提交
39
}
J
Joao Moreno 已提交
40

41 42 43 44 45 46 47
class MainThreadSCMResource implements ISCMResource {

	constructor(
		private sourceControlHandle: number,
		private groupHandle: number,
		private handle: number,
		public sourceUri: URI,
48
		public command: Command | undefined,
49
		public resourceGroup: ISCMResourceGroup,
50
		public decorations: ISCMResourceDecorations
51 52 53 54 55 56 57 58 59 60 61 62
	) { }

	toJSON(): any {
		return {
			$mid: 3,
			sourceControlHandle: this.sourceControlHandle,
			groupHandle: this.groupHandle,
			handle: this.handle
		};
	}
}

J
Joao Moreno 已提交
63 64
class MainThreadSCMProvider implements ISCMProvider {

J
Joao Moreno 已提交
65 66 67 68
	private static ID_HANDLE = 0;
	private _id = `scm${MainThreadSCMProvider.ID_HANDLE++}`;
	get id(): string { return this._id; }

69 70
	private _groups: MainThreadSCMResourceGroup[] = [];
	private _groupsByHandle: { [handle: number]: MainThreadSCMResourceGroup; } = Object.create(null);
J
Joao Moreno 已提交
71 72 73 74 75

	get resources(): ISCMResourceGroup[] {
		return this._groups
			.filter(g => g.resources.length > 0 || !g.features.hideWhenEmpty);
	}
J
Joao Moreno 已提交
76

J
Joao Moreno 已提交
77 78
	private _onDidChange = new Emitter<void>();
	get onDidChange(): Event<void> { return this._onDidChange.event; }
J
Joao Moreno 已提交
79

J
Joao Moreno 已提交
80
	private features: SCMProviderFeatures = {};
J
Joao Moreno 已提交
81

J
Joao Moreno 已提交
82
	get handle(): number { return this._handle; }
J
Joao Moreno 已提交
83
	get label(): string { return this._label; }
J
Joao Moreno 已提交
84
	get contextValue(): string { return this._contextValue; }
J
Joao Moreno 已提交
85

86 87 88 89 90 91 92
	get commitTemplate(): string | undefined { return this.features.commitTemplate; }
	get acceptInputCommand(): Command | undefined { return this.features.acceptInputCommand; }
	get statusBarCommands(): Command[] | undefined { return this.features.statusBarCommands; }

	private _onDidChangeCommitTemplate = new Emitter<string>();
	get onDidChangeCommitTemplate(): Event<string> { return this._onDidChangeCommitTemplate.event; }

J
Joao Moreno 已提交
93 94 95
	private _count: number | undefined = undefined;
	get count(): number | undefined { return this._count; }

J
Joao Moreno 已提交
96 97
	constructor(
		private proxy: ExtHostSCMShape,
J
Joao Moreno 已提交
98
		private _handle: number,
J
Joao Moreno 已提交
99
		private _contextValue: string,
J
Joao Moreno 已提交
100
		private _label: string,
J
Joao Moreno 已提交
101 102
		@ISCMService scmService: ISCMService,
		@ICommandService private commandService: ICommandService
J
Joao Moreno 已提交
103 104 105
	) { }

	$updateSourceControl(features: SCMProviderFeatures): void {
J
Joao Moreno 已提交
106 107 108 109
		if ('count' in features) {
			this._count = features.count;
		}

J
Joao Moreno 已提交
110 111
		this.features = assign(this.features, features);
		this._onDidChange.fire();
112 113 114 115

		if (typeof features.commitTemplate !== 'undefined') {
			this._onDidChangeCommitTemplate.fire(this.commitTemplate);
		}
J
Joao Moreno 已提交
116 117 118
	}

	$registerGroup(handle: number, id: string, label: string): void {
119 120
		const group = new MainThreadSCMResourceGroup(
			this.handle,
121
			handle,
122 123
			this,
			{},
J
Joao Moreno 已提交
124
			label,
125 126 127
			id,
			[]
		);
J
Joao Moreno 已提交
128 129 130

		this._groups.push(group);
		this._groupsByHandle[handle] = group;
J
Joao Moreno 已提交
131 132
	}

J
Joao Moreno 已提交
133 134 135 136
	$updateGroup(handle: number, features: SCMGroupFeatures): void {
		const group = this._groupsByHandle[handle];

		if (!group) {
137
			return;
J
Joao Moreno 已提交
138 139
		}

J
Joao Moreno 已提交
140 141
		group.features = assign(group.features, features);
		this._onDidChange.fire();
J
Joao Moreno 已提交
142 143
	}

144 145 146 147 148 149 150 151 152 153 154
	$updateGroupLabel(handle: number, label: string): void {
		const group = this._groupsByHandle[handle];

		if (!group) {
			return;
		}

		group.label = label;
		this._onDidChange.fire();
	}

155 156
	$updateGroupResourceStates(groupHandle: number, resources: SCMRawResource[]): void {
		const group = this._groupsByHandle[groupHandle];
J
Joao Moreno 已提交
157 158 159

		if (!group) {
			return;
J
Joao Moreno 已提交
160 161
		}

J
Joao Moreno 已提交
162
		group.resources = resources.map(rawResource => {
163
			const [handle, sourceUri, command, icons, tooltip, strikeThrough, faded] = rawResource;
J
Joao Moreno 已提交
164 165 166 167 168
			const icon = icons[0];
			const iconDark = icons[1] || icon;
			const decorations = {
				icon: icon && URI.parse(icon),
				iconDark: iconDark && URI.parse(iconDark),
169
				tooltip,
170 171
				strikeThrough,
				faded
J
Joao Moreno 已提交
172 173
			};

174 175
			return new MainThreadSCMResource(
				this.handle,
176
				groupHandle,
177 178
				handle,
				URI.parse(sourceUri),
J
Joao Moreno 已提交
179
				command,
180
				group,
J
Joao Moreno 已提交
181
				decorations
182
			);
J
Joao Moreno 已提交
183 184 185
		});

		this._onDidChange.fire();
J
Joao Moreno 已提交
186 187
	}

J
Joao Moreno 已提交
188 189 190 191 192 193
	$unregisterGroup(handle: number): void {
		const group = this._groupsByHandle[handle];

		if (!group) {
			return;
		}
J
Joao Moreno 已提交
194

J
Joao Moreno 已提交
195 196 197
		delete this._groupsByHandle[handle];
		this._groups.splice(this._groups.indexOf(group), 1);
	}
J
Joao Moreno 已提交
198

J
Joao Moreno 已提交
199 200 201 202 203 204
	getOriginalResource(uri: URI): TPromise<URI> {
		if (!this.features.hasQuickDiffProvider) {
			return TPromise.as(null);
		}

		return this.proxy.$provideOriginalResource(this.handle, uri);
J
Joao Moreno 已提交
205 206
	}

J
Joao Moreno 已提交
207 208 209 210 211 212 213
	toJSON(): any {
		return {
			$mid: 5,
			handle: this.handle
		};
	}

J
Joao Moreno 已提交
214
	dispose(): void {
J
Joao Moreno 已提交
215

J
Joao Moreno 已提交
216 217 218
	}
}

219
@extHostNamedCustomer(MainContext.MainThreadSCM)
220
export class MainThreadSCM implements MainThreadSCMShape {
J
Joao Moreno 已提交
221

J
Joao Moreno 已提交
222
	private _proxy: ExtHostSCMShape;
J
Joao Moreno 已提交
223 224
	private _repositories: { [handle: number]: ISCMRepository; } = Object.create(null);
	private _inputDisposables: { [handle: number]: IDisposable; } = Object.create(null);
J
Joao Moreno 已提交
225
	private _disposables: IDisposable[] = [];
J
Joao Moreno 已提交
226 227

	constructor(
228
		extHostContext: IExtHostContext,
229
		@IInstantiationService private instantiationService: IInstantiationService,
J
Joao Moreno 已提交
230 231
		@ISCMService private scmService: ISCMService,
		@ICommandService private commandService: ICommandService
J
Joao Moreno 已提交
232
	) {
233
		this._proxy = extHostContext.get(ExtHostContext.ExtHostSCM);
J
Joao Moreno 已提交
234 235
	}

236
	dispose(): void {
J
Joao Moreno 已提交
237 238 239
		Object.keys(this._repositories)
			.forEach(id => this._repositories[id].dispose());
		this._repositories = Object.create(null);
240

J
Joao Moreno 已提交
241 242 243
		Object.keys(this._inputDisposables)
			.forEach(id => this._inputDisposables[id].dispose());
		this._inputDisposables = Object.create(null);
244 245 246 247

		this._disposables = dispose(this._disposables);
	}

J
Joao Moreno 已提交
248 249
	$registerSourceControl(handle: number, id: string, label: string): void {
		const provider = new MainThreadSCMProvider(this._proxy, handle, id, label, this.scmService, this.commandService);
J
Joao Moreno 已提交
250 251
		const repository = this.scmService.registerSCMProvider(provider);
		this._repositories[handle] = repository;
J
Joao Moreno 已提交
252

J
Joao Moreno 已提交
253 254
		const inputDisposable = repository.input.onDidChange(value => this._proxy.$onInputBoxValueChange(handle, value));
		this._inputDisposables[handle] = inputDisposable;
J
Joao Moreno 已提交
255 256 257
	}

	$updateSourceControl(handle: number, features: SCMProviderFeatures): void {
J
Joao Moreno 已提交
258
		const repository = this._repositories[handle];
J
Joao Moreno 已提交
259

J
Joao Moreno 已提交
260
		if (!repository) {
J
Joao Moreno 已提交
261 262 263
			return;
		}

J
Joao Moreno 已提交
264 265
		const provider = repository.provider as MainThreadSCMProvider;
		provider.$updateSourceControl(features);
J
Joao Moreno 已提交
266 267 268
	}

	$unregisterSourceControl(handle: number): void {
J
Joao Moreno 已提交
269
		const repository = this._repositories[handle];
J
Joao Moreno 已提交
270

J
Joao Moreno 已提交
271
		if (!repository) {
J
Joao Moreno 已提交
272 273
			return;
		}
274

J
Joao Moreno 已提交
275 276
		this._inputDisposables[handle].dispose();
		delete this._inputDisposables[handle];
J
Joao Moreno 已提交
277

J
Joao Moreno 已提交
278 279
		repository.dispose();
		delete this._repositories[handle];
J
Joao Moreno 已提交
280 281
	}

J
Joao Moreno 已提交
282
	$registerGroup(sourceControlHandle: number, groupHandle: number, id: string, label: string): void {
J
Joao Moreno 已提交
283
		const repository = this._repositories[sourceControlHandle];
J
Joao Moreno 已提交
284

J
Joao Moreno 已提交
285
		if (!repository) {
J
Joao Moreno 已提交
286 287 288
			return;
		}

J
Joao Moreno 已提交
289
		const provider = repository.provider as MainThreadSCMProvider;
J
Joao Moreno 已提交
290
		provider.$registerGroup(groupHandle, id, label);
J
Joao Moreno 已提交
291 292
	}

J
Joao Moreno 已提交
293
	$updateGroup(sourceControlHandle: number, groupHandle: number, features: SCMGroupFeatures): void {
J
Joao Moreno 已提交
294
		const repository = this._repositories[sourceControlHandle];
J
Joao Moreno 已提交
295

J
Joao Moreno 已提交
296
		if (!repository) {
J
Joao Moreno 已提交
297 298 299
			return;
		}

J
Joao Moreno 已提交
300
		const provider = repository.provider as MainThreadSCMProvider;
J
Joao Moreno 已提交
301 302 303
		provider.$updateGroup(groupHandle, features);
	}

304
	$updateGroupLabel(sourceControlHandle: number, groupHandle: number, label: string): void {
J
Joao Moreno 已提交
305
		const repository = this._repositories[sourceControlHandle];
306

J
Joao Moreno 已提交
307
		if (!repository) {
308 309 310
			return;
		}

J
Joao Moreno 已提交
311
		const provider = repository.provider as MainThreadSCMProvider;
312 313 314
		provider.$updateGroupLabel(groupHandle, label);
	}

J
Joao Moreno 已提交
315
	$updateGroupResourceStates(sourceControlHandle: number, groupHandle: number, resources: SCMRawResource[]): void {
J
Joao Moreno 已提交
316
		const repository = this._repositories[sourceControlHandle];
J
Joao Moreno 已提交
317

J
Joao Moreno 已提交
318
		if (!repository) {
J
Joao Moreno 已提交
319 320
			return;
		}
J
Joao Moreno 已提交
321

J
Joao Moreno 已提交
322
		const provider = repository.provider as MainThreadSCMProvider;
J
Joao Moreno 已提交
323
		provider.$updateGroupResourceStates(groupHandle, resources);
J
Joao Moreno 已提交
324 325
	}

J
Joao Moreno 已提交
326
	$unregisterGroup(sourceControlHandle: number, handle: number): void {
J
Joao Moreno 已提交
327
		const repository = this._repositories[sourceControlHandle];
J
Joao Moreno 已提交
328

J
Joao Moreno 已提交
329
		if (!repository) {
J
Joao Moreno 已提交
330 331 332
			return;
		}

J
Joao Moreno 已提交
333
		const provider = repository.provider as MainThreadSCMProvider;
J
Joao Moreno 已提交
334
		provider.$unregisterGroup(handle);
J
Joao Moreno 已提交
335 336
	}

J
Joao Moreno 已提交
337 338 339 340 341 342 343 344
	$setInputBoxValue(sourceControlHandle: number, value: string): void {
		const repository = this._repositories[sourceControlHandle];

		if (!repository) {
			return;
		}

		repository.input.value = value;
345
	}
346 347 348 349 350 351 352 353 354 355

	$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void {
		const repository = this._repositories[sourceControlHandle];

		if (!repository) {
			return;
		}

		repository.input.placeholder = placeholder;
	}
J
Joao Moreno 已提交
356
}