workspaceEditingService.ts 3.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import { IWorkspaceEditingService } from "vs/workbench/services/workspace/common/workspaceEditing";
import URI from "vs/base/common/uri";
import { equals, distinct } from "vs/base/common/arrays";
import { TPromise } from "vs/base/common/winjs.base";
import { IWorkspaceContextService } from "vs/platform/workspace/common/workspace";
import { IConfigurationEditingService, ConfigurationTarget } from "vs/workbench/services/configuration/common/configurationEditing";
import { IConfigurationService } from "vs/platform/configuration/common/configuration";

interface IWorkspaceConfiguration {
	[master: string]: {
		folders: string[];
	};
}

const workspaceConfigKey = 'workspace';

export class WorkspaceEditingService implements IWorkspaceEditingService {

	public _serviceBrand: any;

	constructor(
		@IConfigurationEditingService private configurationEditingService: IConfigurationEditingService,
		@IConfigurationService private configurationService: IConfigurationService,
		@IWorkspaceContextService private contextService: IWorkspaceContextService
	) {
	}

	public addRoots(rootsToAdd: URI[]): TPromise<void> {
		if (!this.contextService.hasWorkspace()) {
			return TPromise.as(void 0); // we need a workspace to begin with
		}

		const roots = this.contextService.getWorkspace2().roots;

		return this.doSetRoots([...roots, ...rootsToAdd]);
	}

	public removeRoots(rootsToRemove: URI[]): TPromise<void> {
		if (!this.contextService.hasWorkspace()) {
			return TPromise.as(void 0); // we need a workspace to begin with
		}

		const roots = this.contextService.getWorkspace2().roots;
		const rootsToRemoveRaw = rootsToRemove.map(root => root.toString());

		return this.doSetRoots(roots.filter(root => rootsToRemoveRaw.indexOf(root.toString()) === -1));
	}

	public clearRoots(roots: URI[]): TPromise<void> {
		if (!this.contextService.hasWorkspace()) {
			return TPromise.as(void 0); // we need a workspace to begin with
		}

		return this.doSetRoots([]);
	}

	private doSetRoots(roots: URI[]): TPromise<void> {
		const workspaceUserConfig = this.configurationService.lookup(workspaceConfigKey).user as IWorkspaceConfiguration || Object.create(null);
		const master = this.contextService.getWorkspace2().roots[0].toString();

		const currentWorkspaceRoots = (workspaceUserConfig[master.toString()] && workspaceUserConfig[master.toString()].folders) || [];
		const newWorkspaceRoots = distinct(roots.map(root => root.toString()));

		// Make sure we do not set the master folder as root
		const masterIndex = newWorkspaceRoots.indexOf(master);
		if (masterIndex >= 0) {
			newWorkspaceRoots.splice(masterIndex, 1);
		}

		// See if there are any changes
		if (equals(currentWorkspaceRoots, newWorkspaceRoots)) {
			return TPromise.as(void 0);
		}

		// Apply to config
		workspaceUserConfig[master.toString()] = {
			folders: newWorkspaceRoots
		};

		return this.configurationEditingService.writeConfiguration(ConfigurationTarget.USER, { key: workspaceConfigKey, value: workspaceUserConfig }).then(() => void 0);
	}
}