extensionsActions.ts 21.2 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.
 *--------------------------------------------------------------------------------------------*/

J
Joao Moreno 已提交
6
import 'vs/css!./media/extensionActions';
J
Joao Moreno 已提交
7
import { localize } from 'vs/nls';
J
Joao Moreno 已提交
8
import { TPromise } from 'vs/base/common/winjs.base';
E
Erich Gamma 已提交
9
import { Action } from 'vs/base/common/actions';
10
import severity from 'vs/base/common/severity';
11
import paths = require('vs/base/common/paths');
J
Joao Moreno 已提交
12
import Event from 'vs/base/common/event';
J
Joao Moreno 已提交
13
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
J
Joao Moreno 已提交
14
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
15
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewlet, ConfigurationKey } from './extensions';
J
Joao Moreno 已提交
16
import { LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement';
17
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
18
import { IMessageService, LaterAction } from 'vs/platform/message/common/message';
19
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
20 21 22
import { ToggleViewletAction } from 'vs/workbench/browser/viewlet';
import { IViewletService } from 'vs/workbench/services/viewlet/common/viewletService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
J
Joao Moreno 已提交
23
import { Query } from '../common/extensionQuery';
J
Joao Moreno 已提交
24
import { shell, remote } from 'electron';
J
Joao Moreno 已提交
25 26 27 28
import { InitialContent } from 'vs/workbench/parts/extensions/electron-browser/extensionsFileTemplate';
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import URI from 'vs/base/common/uri';
J
Joao Moreno 已提交
29 30

const dialog = remote.dialog;
J
Joao Moreno 已提交
31

32 33
export class InstallAction extends Action {

J
Joao Moreno 已提交
34 35
	private static InstallLabel = localize('installAction', "Install");
	private static InstallingLabel = localize('installing', "Installing");
J
Joao Moreno 已提交
36 37 38 39

	private static Class = 'extension-action install';
	private static InstallingClass = 'extension-action install installing';

J
Joao Moreno 已提交
40
	private disposables: IDisposable[] = [];
J
Joao Moreno 已提交
41 42 43
	private _extension: IExtension;
	get extension(): IExtension { return this._extension; }
	set extension(extension: IExtension) { this._extension = extension; this.update(); }
44

45 46 47
	constructor(
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
J
Joao Moreno 已提交
48
		super('extensions.install', InstallAction.InstallLabel, InstallAction.Class, false);
49

50
		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
J
Joao Moreno 已提交
51
		this.update();
52 53
	}

J
Joao Moreno 已提交
54
	private update(): void {
J
Joao Moreno 已提交
55
		if (!this.extension || this.extension.type === LocalExtensionType.System) {
J
Joao Moreno 已提交
56
			this.enabled = false;
J
Joao Moreno 已提交
57
			this.class = InstallAction.Class;
J
Joao Moreno 已提交
58 59 60 61
			this.label = InstallAction.InstallLabel;
			return;
		}

62
		this.enabled = this.extensionsWorkbenchService.canInstall(this.extension) && this.extension.state === ExtensionState.Uninstalled;
J
Joao Moreno 已提交
63 64 65 66 67 68 69 70

		if (this.extension.state === ExtensionState.Installing) {
			this.label = InstallAction.InstallingLabel;
			this.class = InstallAction.InstallingClass;
		} else {
			this.label = InstallAction.InstallLabel;
			this.class = InstallAction.Class;
		}
71 72
	}

J
Joao Moreno 已提交
73
	run(): TPromise<any> {
74
		return this.extensionsWorkbenchService.install(this.extension);
75 76
	}

J
Joao Moreno 已提交
77 78 79
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
80 81
	}
}
J
Joao Moreno 已提交
82

J
Joao Moreno 已提交
83
export class UninstallAction extends Action {
J
Joao Moreno 已提交
84

J
Joao Moreno 已提交
85
	private disposables: IDisposable[] = [];
J
Joao Moreno 已提交
86 87 88
	private _extension: IExtension;
	get extension(): IExtension { return this._extension; }
	set extension(extension: IExtension) { this._extension = extension; this.update(); }
J
Joao Moreno 已提交
89

90
	constructor(
91 92 93
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
		@IMessageService private messageService: IMessageService,
		@IInstantiationService private instantiationService: IInstantiationService
94
	) {
J
Joao Moreno 已提交
95
		super('extensions.uninstall', localize('uninstall', "Uninstall"), 'extension-action uninstall', false);
J
Joao Moreno 已提交
96

J
Joao Moreno 已提交
97 98
		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
		this.update();
J
Joao Moreno 已提交
99
	}
J
Joao Moreno 已提交
100

J
Joao Moreno 已提交
101 102 103 104 105 106
	private update(): void {
		if (!this.extension) {
			this.enabled = false;
			return;
		}

J
Joao Moreno 已提交
107 108 109 110 111 112
		if (this.extension.type !== LocalExtensionType.User) {
			this.enabled = false;
			return;
		}

		this.enabled = this.extension.state === ExtensionState.Installed || this.extension.state === ExtensionState.NeedsRestart;
J
Joao Moreno 已提交
113
	}
J
Joao Moreno 已提交
114

J
Joao Moreno 已提交
115
	run(): TPromise<any> {
J
Joao Moreno 已提交
116
		if (!window.confirm(localize('deleteSure', "Are you sure you want to uninstall '{0}'?", this.extension.displayName))) {
J
Joao Moreno 已提交
117 118
			return TPromise.as(null);
		}
J
Joao Moreno 已提交
119

120 121 122
		return this.extensionsWorkbenchService.uninstall(this.extension).then(() => {
			this.messageService.show(severity.Info, {
				message: localize('postUninstallMessage', "{0} was successfully uninstalled. Restart to deactivate it.", this.extension.displayName),
123
				actions: [this.instantiationService.createInstance(ReloadWindowAction, ReloadWindowAction.ID, localize('restartNow', "Restart Now")), LaterAction]
124 125
			});
		});
J
Joao Moreno 已提交
126
	}
J
Joao Moreno 已提交
127

J
Joao Moreno 已提交
128 129 130 131 132
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
}
J
Joao Moreno 已提交
133 134 135

export class CombinedInstallAction extends Action {

J
Joao Moreno 已提交
136
	private static NoExtensionClass = 'extension-action install no-extension';
J
Joao Moreno 已提交
137 138 139
	private installAction: InstallAction;
	private uninstallAction: UninstallAction;
	private disposables: IDisposable[] = [];
J
Joao Moreno 已提交
140 141 142 143 144 145 146
	private _extension: IExtension;
	get extension(): IExtension { return this._extension; }
	set extension(extension: IExtension) {
		this._extension = extension;
		this.installAction.extension = extension;
		this.uninstallAction.extension = extension;
	}
J
Joao Moreno 已提交
147

148 149 150
	constructor(
		@IInstantiationService instantiationService: IInstantiationService
	) {
J
Joao Moreno 已提交
151 152
		super('extensions.combinedInstall', '', '', false);

J
Joao Moreno 已提交
153 154
		this.installAction = instantiationService.createInstance(InstallAction);
		this.uninstallAction = instantiationService.createInstance(UninstallAction);
J
Joao Moreno 已提交
155 156
		this.disposables.push(this.installAction, this.uninstallAction);

157
		this.installAction.onDidChange(this.update, this, this.disposables);
158
		this.uninstallAction.onDidChange(this.update, this, this.disposables);
J
Joao Moreno 已提交
159 160 161 162
		this.update();
	}

	private update(): void {
J
Joao Moreno 已提交
163
		if (!this.extension || this.extension.type === LocalExtensionType.System) {
J
Joao Moreno 已提交
164 165 166
			this.enabled = false;
			this.class = CombinedInstallAction.NoExtensionClass;
		} else if (this.installAction.enabled) {
J
Joao Moreno 已提交
167 168 169 170 171 172 173
			this.enabled = true;
			this.label = this.installAction.label;
			this.class = this.installAction.class;
		} else if (this.uninstallAction.enabled) {
			this.enabled = true;
			this.label = this.uninstallAction.label;
			this.class = this.uninstallAction.class;
J
Joao Moreno 已提交
174 175 176 177
		} else if (this.extension.state === ExtensionState.Installing) {
			this.enabled = false;
			this.label = this.installAction.label;
			this.class = this.installAction.class;
J
Joao Moreno 已提交
178 179
		} else {
			this.enabled = false;
J
Joao Moreno 已提交
180 181
			this.label = this.installAction.label;
			this.class = this.installAction.class;
J
Joao Moreno 已提交
182 183 184 185 186 187 188 189 190 191 192 193 194
		}
	}

	run(): TPromise<any> {
		if (this.installAction.enabled) {
			return this.installAction.run();
		} else if (this.uninstallAction.enabled) {
			return this.uninstallAction.run();
		}

		return TPromise.as(null);
	}

J
Joao Moreno 已提交
195 196 197 198 199 200 201 202
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
}

export class UpdateAction extends Action {

J
Joao Moreno 已提交
203
	private static EnabledClass = 'extension-action update';
J
Johannes Rieken 已提交
204
	private static DisabledClass = `${UpdateAction.EnabledClass} disabled`;
J
Joao Moreno 已提交
205 206

	private disposables: IDisposable[] = [];
J
Joao Moreno 已提交
207 208 209
	private _extension: IExtension;
	get extension(): IExtension { return this._extension; }
	set extension(extension: IExtension) { this._extension = extension; this.update(); }
J
Joao Moreno 已提交
210

211 212 213
	constructor(
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
J
Joao Moreno 已提交
214
		super('extensions.update', localize('updateAction', "Update"), UpdateAction.DisabledClass, false);
J
Joao Moreno 已提交
215

J
Joao Moreno 已提交
216 217
		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
		this.update();
J
Joao Moreno 已提交
218 219
	}

J
Joao Moreno 已提交
220 221 222 223 224 225 226
	private update(): void {
		if (!this.extension) {
			this.enabled = false;
			this.class = UpdateAction.DisabledClass;
			return;
		}

J
Joao Moreno 已提交
227 228 229 230 231 232
		if (this.extension.type !== LocalExtensionType.User) {
			this.enabled = false;
			this.class = UpdateAction.DisabledClass;
			return;
		}

233
		const canInstall = this.extensionsWorkbenchService.canInstall(this.extension);
J
Joao Moreno 已提交
234 235
		const isInstalled = this.extension.state === ExtensionState.Installed
			|| this.extension.state === ExtensionState.NeedsRestart;
J
Joao Moreno 已提交
236

237
		this.enabled = canInstall && isInstalled && this.extension.outdated;
238 239 240
		this.class = this.enabled ? UpdateAction.EnabledClass : UpdateAction.DisabledClass;
	}

J
Joao Moreno 已提交
241
	run(): TPromise<any> {
242
		return this.extensionsWorkbenchService.install(this.extension);
J
Joao Moreno 已提交
243 244
	}

J
Joao Moreno 已提交
245 246 247 248 249 250 251 252 253
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
}

export class EnableAction extends Action {

	private static EnabledClass = 'extension-action enable';
J
Johannes Rieken 已提交
254
	private static DisabledClass = `${EnableAction.EnabledClass} disabled`;
J
Joao Moreno 已提交
255 256

	private disposables: IDisposable[] = [];
J
Joao Moreno 已提交
257 258 259
	private _extension: IExtension;
	get extension(): IExtension { return this._extension; }
	set extension(extension: IExtension) { this._extension = extension; this.update(); }
J
Joao Moreno 已提交
260 261 262 263 264 265 266

	constructor(
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
		@IInstantiationService private instantiationService: IInstantiationService
	) {
		super('extensions.enable', localize('enableAction', "Enable"), EnableAction.DisabledClass, false);

J
Joao Moreno 已提交
267 268
		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
		this.update();
J
Joao Moreno 已提交
269 270
	}

J
Joao Moreno 已提交
271 272 273 274 275 276 277
	private update(): void {
		if (!this.extension) {
			this.enabled = false;
			this.class = EnableAction.DisabledClass;
			return;
		}

J
Joao Moreno 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290
		this.enabled = this.extension.state === ExtensionState.NeedsRestart;
		this.class = this.enabled ? EnableAction.EnabledClass : EnableAction.DisabledClass;
	}

	run(): TPromise<any> {
		if (!window.confirm(localize('restart', "In order to enable this extension, this window of VS Code needs to be restarted.\n\nDo you want to continue?"))) {
			return TPromise.as(null);
		}

		const action = this.instantiationService.createInstance(ReloadWindowAction, ReloadWindowAction.ID, localize('restartNow', "Restart Now"));
		return action.run();
	}

J
Joao Moreno 已提交
291 292 293 294
	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
295
}
J
Joao Moreno 已提交
296 297 298

export class UpdateAllAction extends Action {

J
Joao Moreno 已提交
299
	static ID = 'workbench.extensions.action.updateAllExtensions';
300 301
	static LABEL = localize('updateAll', "Update All Extensions");

J
Joao Moreno 已提交
302 303 304
	private disposables: IDisposable[] = [];

	constructor(
305 306
		id = UpdateAllAction.ID,
		label = UpdateAllAction.LABEL,
J
Joao Moreno 已提交
307 308
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
309
		super(id, label, '', false);
J
Joao Moreno 已提交
310 311 312 313 314

		this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
		this.update();
	}

315 316
	private get outdated(): IExtension[] {
		return this.extensionsWorkbenchService.local.filter(
J
Joao Moreno 已提交
317
			e => this.extensionsWorkbenchService.canInstall(e)
318 319 320
				&& e.type === LocalExtensionType.User
				&& (e.state === ExtensionState.Installed || e.state === ExtensionState.NeedsRestart)
				&& e.outdated
J
Joao Moreno 已提交
321
		);
J
Joao Moreno 已提交
322 323 324
	}

	private update(): void {
325
		this.enabled = this.outdated.length > 0;
J
Joao Moreno 已提交
326 327
	}

J
Johannes Rieken 已提交
328
	run(promptToInstallDependencies: boolean = true, ): TPromise<any> {
329
		return TPromise.join(this.outdated.map(e => this.extensionsWorkbenchService.install(e, promptToInstallDependencies)));
J
Joao Moreno 已提交
330 331 332 333 334 335 336
	}

	dispose(): void {
		super.dispose();
		this.disposables = dispose(this.disposables);
	}
}
337 338 339

export class OpenExtensionsViewletAction extends ToggleViewletAction {

J
Joao Moreno 已提交
340
	static ID = VIEWLET_ID;
341 342 343 344 345 346 347 348 349 350 351 352
	static LABEL = localize('toggleExtensionsViewlet', "Show Extensions");

	constructor(
		id: string,
		label: string,
		@IViewletService viewletService: IViewletService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, VIEWLET_ID, viewletService, editorService);
	}
}

I
isidor 已提交
353 354 355 356 357
export class InstallExtensionsAction extends OpenExtensionsViewletAction {
	static ID = 'workbench.extensions.action.installExtensions';
	static LABEL = localize('installExtensions', "Install Extensions");
}

J
Joao Moreno 已提交
358
export class ShowInstalledExtensionsAction extends Action {
359

J
Joao Moreno 已提交
360 361
	static ID = 'workbench.extensions.action.showInstalledExtensions';
	static LABEL = localize('showInstalledExtensions', "Show Installed Extensions");
362 363 364 365

	constructor(
		id: string,
		label: string,
366 367
		@IViewletService private viewletService: IViewletService,
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
368
	) {
369
		super(id, label, 'clear-extensions', true);
370 371 372 373 374 375
	}

	run(): TPromise<void> {
		return this.viewletService.openViewlet(VIEWLET_ID, true)
			.then(viewlet => viewlet as IExtensionsViewlet)
			.then(viewlet => {
376
				viewlet.search('');
377 378 379 380 381
				viewlet.focus();
			});
	}
}

J
Joao Moreno 已提交
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
export class ClearExtensionsInputAction extends ShowInstalledExtensionsAction {

	static ID = 'workbench.extensions.action.clearExtensionsInput';
	static LABEL = localize('clearExtensionsInput', "Clear Extensions Input");

	private disposables: IDisposable[] = [];

	constructor(
		id: string,
		label: string,
		onSearchChange: Event<string>,
		@IViewletService viewletService: IViewletService,
		@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
		super(id, label, viewletService, extensionsWorkbenchService);
397
		this.enabled = false;
J
Joao Moreno 已提交
398 399 400 401 402 403 404 405 406 407 408 409
		onSearchChange(this.onSearchChange, this, this.disposables);
	}

	private onSearchChange(value: string): void {
		this.enabled = !!value;
	}

	dispose(): void {
		this.disposables = dispose(this.disposables);
	}
}

J
Joao Moreno 已提交
410
export class ShowOutdatedExtensionsAction extends Action {
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426

	static ID = 'workbench.extensions.action.listOutdatedExtensions';
	static LABEL = localize('showOutdatedExtensions', "Show Outdated Extensions");

	constructor(
		id: string,
		label: string,
		@IViewletService private viewletService: IViewletService
	) {
		super(id, label, null, true);
	}

	run(): TPromise<void> {
		return this.viewletService.openViewlet(VIEWLET_ID, true)
			.then(viewlet => viewlet as IExtensionsViewlet)
			.then(viewlet => {
427
				viewlet.search('@outdated ');
428 429 430 431 432 433 434 435
				viewlet.focus();
			});
	}

	protected isEnabled(): boolean {
		return true;
	}
}
J
Joao Moreno 已提交
436 437 438 439 440 441 442 443 444 445 446

export class ShowPopularExtensionsAction extends Action {

	static ID = 'workbench.extensions.action.showPopularExtensions';
	static LABEL = localize('showPopularExtensions', "Show Popular Extensions");

	constructor(
		id: string,
		label: string,
		@IViewletService private viewletService: IViewletService
	) {
447
		super(id, label, null, true);
J
Joao Moreno 已提交
448 449 450 451 452 453
	}

	run(): TPromise<void> {
		return this.viewletService.openViewlet(VIEWLET_ID, true)
			.then(viewlet => viewlet as IExtensionsViewlet)
			.then(viewlet => {
454
				viewlet.search('@sort:installs ');
J
Joao Moreno 已提交
455 456 457 458 459 460 461 462 463
				viewlet.focus();
			});
	}

	protected isEnabled(): boolean {
		return true;
	}
}

J
Joao Moreno 已提交
464
export class ShowRecommendedExtensionsAction extends Action {
J
Joao Moreno 已提交
465

J
Joao Moreno 已提交
466
	static ID = 'workbench.extensions.action.showRecommendedExtensions';
J
Joao Moreno 已提交
467
	static LABEL = localize('showRecommendedExtensions', "Show Recommended Extensions");
J
Joao Moreno 已提交
468 469 470 471 472 473

	constructor(
		id: string,
		label: string,
		@IViewletService private viewletService: IViewletService
	) {
474
		super(id, label, null, true);
J
Joao Moreno 已提交
475 476 477 478 479 480
	}

	run(): TPromise<void> {
		return this.viewletService.openViewlet(VIEWLET_ID, true)
			.then(viewlet => viewlet as IExtensionsViewlet)
			.then(viewlet => {
481
				viewlet.search('@recommended ');
J
Joao Moreno 已提交
482 483 484 485
				viewlet.focus();
			});
	}

J
Joao Moreno 已提交
486 487 488 489 490
	protected isEnabled(): boolean {
		return true;
	}
}

S
Sandeep Somavarapu 已提交
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
export class ShowWorkspaceRecommendedExtensionsAction extends Action {

	static ID = 'workbench.extensions.action.showWorkspaceRecommendedExtensions';
	static LABEL = localize('showWorkspaceRecommendedExtensions', "Show Workspace Recommended Extensions");

	constructor(
		id: string,
		label: string,
		@IViewletService private viewletService: IViewletService
	) {
		super(id, label, null, true);
	}

	run(): TPromise<void> {
		return this.viewletService.openViewlet(VIEWLET_ID, true)
			.then(viewlet => viewlet as IExtensionsViewlet)
			.then(viewlet => {
508
				viewlet.search('@recommended:workspace ');
S
Sandeep Somavarapu 已提交
509 510 511 512 513 514 515 516 517
				viewlet.focus();
			});
	}

	protected isEnabled(): boolean {
		return true;
	}
}

J
Joao Moreno 已提交
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
export class ChangeSortAction extends Action {

	private query: Query;
	private disposables: IDisposable[] = [];

	constructor(
		id: string,
		label: string,
		onSearchChange: Event<string>,
		private sortBy: string,
		private sortOrder: string,
		@IViewletService private viewletService: IViewletService
	) {
		super(id, label, null, true);

J
Joao Moreno 已提交
533
		if (sortBy === undefined && sortOrder === undefined) {
J
Joao Moreno 已提交
534 535 536 537
			throw new Error('bad arguments');
		}

		this.query = Query.parse('');
538
		this.enabled = false;
J
Joao Moreno 已提交
539 540 541 542 543 544
		onSearchChange(this.onSearchChange, this, this.disposables);
	}

	private onSearchChange(value: string): void {
		const query = Query.parse(value);
		this.query = new Query(query.value, this.sortBy || query.sortBy, this.sortOrder || query.sortOrder);
545
		this.enabled = value && this.query.isValid() && !this.query.equals(query);
J
Joao Moreno 已提交
546 547 548 549 550 551 552 553 554 555 556
	}

	run(): TPromise<void> {
		return this.viewletService.openViewlet(VIEWLET_ID, true)
			.then(viewlet => viewlet as IExtensionsViewlet)
			.then(viewlet => {
				viewlet.search(this.query.toString());
				viewlet.focus();
			});
	}

557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
	protected isEnabled(): boolean {
		return true;
	}
}

export class OpenExtensionsFolderAction extends Action {

	static ID = 'workbench.extensions.action.openExtensionsFolder';
	static LABEL = localize('openExtensionsFolder', "Open Extensions Folder");

	constructor(
		id: string,
		label: string,
		@IEnvironmentService private environmentService: IEnvironmentService
	) {
		super(id, label, null, true);
	}

	run(): TPromise<any> {
		const extensionsHome = this.environmentService.extensionsPath;
		shell.showItemInFolder(paths.normalize(extensionsHome, true));

		return TPromise.as(true);
	}

J
Joao Moreno 已提交
582 583 584
	protected isEnabled(): boolean {
		return true;
	}
S
Sandeep Somavarapu 已提交
585 586
}

S
Sandeep Somavarapu 已提交
587
export class ConfigureWorkspaceRecommendedExtensionsAction extends Action {
J
Joao Moreno 已提交
588

S
Sandeep Somavarapu 已提交
589 590
	static ID = 'workbench.extensions.action.configureWorkspaceRecommendedExtensions';
	static LABEL = localize('configureWorkspaceRecommendedExtensions', "Configure Workspace Recommended Extensions");
S
Sandeep Somavarapu 已提交
591

J
Joao Moreno 已提交
592 593 594 595 596 597 598 599 600
	constructor(
		id: string,
		label: string,
		@IFileService private fileService: IFileService,
		@IWorkspaceContextService private contextService: IWorkspaceContextService,
		@IExtensionsWorkbenchService private extensionsService: IExtensionsWorkbenchService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IMessageService private messageService: IMessageService
	) {
S
Sandeep Somavarapu 已提交
601 602 603 604
		super(id, label, null, true);
	}

	public run(event: any): TPromise<any> {
J
Joao Moreno 已提交
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
		return this.openExtensionsFile();
	}

	private openExtensionsFile(): TPromise<any> {
		if (!this.contextService.getWorkspace()) {
			this.messageService.show(severity.Info, localize('ConfigureWorkspaceRecommendations.noWorkspace', 'Recommendations are only available on a workspace folder.'));
			return TPromise.as(undefined);
		}

		return this.getOrCreateExtensionsFile().then(value => {
			return this.editorService.openEditor({
				resource: value.extensionsFileResource,
				options: {
					forceOpen: true,
					pinned: value.created
				},
			});
		}, (error) => TPromise.wrapError(new Error(localize('OpenExtensionsFile.failed', "Unable to create 'extensions.json' file inside the '.vscode' folder ({0}).", error))));
	}

	private getOrCreateExtensionsFile(): TPromise<{ created: boolean, extensionsFileResource: URI }> {
J
Johannes Rieken 已提交
626
		const extensionsFileResource = URI.file(paths.join(this.contextService.getWorkspace().resource.fsPath, '.vscode', `${ConfigurationKey}.json`));
J
Joao Moreno 已提交
627 628 629 630 631 632 633 634

		return this.fileService.resolveContent(extensionsFileResource).then(content => {
			return { created: false, extensionsFileResource };
		}, err => {
			return this.fileService.updateContent(extensionsFileResource, InitialContent).then(() => {
				return { created: true, extensionsFileResource };
			});
		});
S
Sandeep Somavarapu 已提交
635
	}
J
Joao Moreno 已提交
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
}

export class InstallVSIXAction extends Action {

	static ID = 'workbench.extensions.action.installVSIX';
	static LABEL = localize('installVSIX', "Install from VSIX...");

	constructor(
		id = InstallVSIXAction.ID,
		label = InstallVSIXAction.LABEL,
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
	) {
		super(id, label, 'extension-action install-vsix', true);
	}

	run(): TPromise<any> {
		const result = dialog.showOpenDialog(remote.getCurrentWindow(), {
			filters: [{ name: 'VSIX Extensions', extensions: ['vsix'] }],
			properties: ['openFile']
		});

		if (!result) {
			return TPromise.as(null);
		}

		return TPromise.join(result.map(vsix => this.extensionsWorkbenchService.install(vsix)));
	}
J
Joao Moreno 已提交
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
}

export class BuiltinStatusLabelAction extends Action {

	private static Class = 'extension-action built-in-status';

	private _extension: IExtension;
	get extension(): IExtension { return this._extension; }
	set extension(extension: IExtension) { this._extension = extension; this.update(); }

	constructor() {
		super('extensions.install', localize('builtin', "Built-in"), '', false);
	}

	private update(): void {
		if (this.extension && this.extension.type === LocalExtensionType.System) {
J
Johannes Rieken 已提交
679
			this.class = `${BuiltinStatusLabelAction.Class} system`;
J
Joao Moreno 已提交
680
		} else {
J
Johannes Rieken 已提交
681
			this.class = `${BuiltinStatusLabelAction.Class} user`;
J
Joao Moreno 已提交
682 683 684 685 686 687 688
		}
	}

	run(): TPromise<any> {
		return TPromise.as(null);
	}
}