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

'use strict';

8
import {TPromise} from 'vs/base/common/winjs.base';
E
Erich Gamma 已提交
9
import {WorkbenchShell} from 'vs/workbench/electron-browser/shell';
10
import {IOptions} from 'vs/workbench/common/options';
11
import {domContentLoaded} from 'vs/base/browser/dom';
E
Erich Gamma 已提交
12 13 14 15 16 17 18
import errors = require('vs/base/common/errors');
import platform = require('vs/base/common/platform');
import paths = require('vs/base/common/paths');
import timer = require('vs/base/common/timer');
import uri from 'vs/base/common/uri';
import strings = require('vs/base/common/strings');
import {IResourceInput} from 'vs/platform/editor/common/editor';
19
import {EventService} from 'vs/platform/event/common/eventService';
20
import {LegacyWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService';
21
import {IWorkspace} from 'vs/platform/workspace/common/workspace';
B
Benjamin Pasero 已提交
22
import {WorkspaceConfigurationService} from 'vs/workbench/services/configuration/node/configurationService';
23
import {IProcessEnvironment} from 'vs/code/electron-main/env';
B
Benjamin Pasero 已提交
24
import {ParsedArgs} from 'vs/platform/environment/node/argv';
25
import {realpath} from 'vs/base/node/pfs';
J
Joao Moreno 已提交
26
import {EnvironmentService} from 'vs/platform/environment/node/environmentService';
E
Erich Gamma 已提交
27 28 29
import path = require('path');
import fs = require('fs');
import gracefulFs = require('graceful-fs');
30
import {IPath, IOpenFileRequest} from 'vs/workbench/electron-browser/common';
B
Benjamin Pasero 已提交
31 32

gracefulFs.gracefulify(fs); // enable gracefulFs
E
Erich Gamma 已提交
33

34
const timers = (<any>window).MonacoEnvironment.timers;
A
Alex Dima 已提交
35

36
export interface IWindowConfiguration extends ParsedArgs, IOpenFileRequest {
37 38 39 40 41
	appRoot: string;
	execPath: string;

	userEnv: IProcessEnvironment;

E
Erich Gamma 已提交
42
	workspacePath?: string;
43

E
Erich Gamma 已提交
44 45 46
	extensionsToInstall?: string[];
}

47
export function startup(configuration: IWindowConfiguration): TPromise<void> {
48

E
Erich Gamma 已提交
49
	// Shell Options
B
polish  
Benjamin Pasero 已提交
50 51 52
	const filesToOpen = configuration.filesToOpen && configuration.filesToOpen.length ? toInputs(configuration.filesToOpen) : null;
	const filesToCreate = configuration.filesToCreate && configuration.filesToCreate.length ? toInputs(configuration.filesToCreate) : null;
	const filesToDiff = configuration.filesToDiff && configuration.filesToDiff.length ? toInputs(configuration.filesToDiff) : null;
B
Benjamin Pasero 已提交
53
	const shellOptions: IOptions = {
54 55 56
		filesToOpen,
		filesToCreate,
		filesToDiff,
57
		extensionsToInstall: configuration.extensionsToInstall
E
Erich Gamma 已提交
58 59
	};

60
	if (configuration.performance) {
E
Erich Gamma 已提交
61 62 63
		timer.ENABLE_TIMER = true;
	}

64 65 66 67 68 69
	// Resolve workspace
	return getWorkspace(configuration.workspacePath).then(workspace => {

		// Open workbench
		return openWorkbench(configuration, workspace, shellOptions);
	});
E
Erich Gamma 已提交
70 71 72 73
}

function toInputs(paths: IPath[]): IResourceInput[] {
	return paths.map(p => {
B
Benjamin Pasero 已提交
74
		const input = <IResourceInput>{
E
Erich Gamma 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
			resource: uri.file(p.filePath)
		};

		if (p.lineNumber) {
			input.options = {
				selection: {
					startLineNumber: p.lineNumber,
					startColumn: p.columnNumber
				}
			};
		}

		return input;
	});
}

91
function getWorkspace(workspacePath: string): TPromise<IWorkspace> {
B
polish  
Benjamin Pasero 已提交
92
	if (!workspacePath) {
93
		return TPromise.as(null);
E
Erich Gamma 已提交
94 95
	}

96 97
	return realpath(workspacePath).then(realWorkspacePath => {

E
Erich Gamma 已提交
98 99 100 101
		// for some weird reason, node adds a trailing slash to UNC paths
		// we never ever want trailing slashes as our workspace path unless
		// someone opens root ("/").
		// See also https://github.com/nodejs/io.js/issues/1765
102 103 104
		if (paths.isUNC(realWorkspacePath) && strings.endsWith(realWorkspacePath, paths.nativeSep)) {
			realWorkspacePath = strings.rtrim(realWorkspacePath, paths.nativeSep);
		}
E
Erich Gamma 已提交
105

106 107 108
		const workspaceResource = uri.file(realWorkspacePath);
		const folderName = path.basename(realWorkspacePath) || realWorkspacePath;
		const folderStat = fs.statSync(realWorkspacePath);
E
Erich Gamma 已提交
109

110 111 112 113 114 115 116 117 118 119
		return <IWorkspace>{
			'resource': workspaceResource,
			'name': folderName,
			'uid': platform.isLinux ? folderStat.ino : folderStat.birthtime.getTime() // On Linux, birthtime is ctime, so we cannot use it! We use the ino instead!
		};
	}, (error) => {
		errors.onUnexpectedError(error);

		return null; // treat invalid paths as empty workspace
	});
E
Erich Gamma 已提交
120 121
}

122
function openWorkbench(environment: IWindowConfiguration, workspace: IWorkspace, options: IOptions): TPromise<void> {
B
Benjamin Pasero 已提交
123
	const eventService = new EventService();
J
Joao Moreno 已提交
124
	const environmentService = new EnvironmentService(environment, environment.execPath);
125
	const contextService = new LegacyWorkspaceContextService(workspace, options);
B
Benjamin Pasero 已提交
126
	const configurationService = new WorkspaceConfigurationService(contextService, eventService, environmentService);
127 128 129 130 131 132

	// Since the configuration service is one of the core services that is used in so many places, we initialize it
	// right before startup of the workbench shell to have its data ready for consumers
	return configurationService.initialize().then(() => {
		timers.beforeReady = new Date();

A
Alex Dima 已提交
133
		return domContentLoaded().then(() => {
134 135 136
			timers.afterReady = new Date();

			// Open Shell
B
Benjamin Pasero 已提交
137 138
			const beforeOpen = new Date();
			const shell = new WorkbenchShell(document.body, workspace, {
139 140
				configurationService,
				eventService,
141 142
				contextService,
				environmentService
143
			}, options);
144 145 146
			shell.open();

			shell.joinCreation().then(() => {
B
Benjamin Pasero 已提交
147
				timer.start(timer.Topic.STARTUP, 'Open Shell, Viewconst & Editor', beforeOpen, 'Workbench has opened after this event with viewconst and editor restored').stop();
148 149 150 151 152 153 154 155
			});

			// Inform user about loading issues from the loader
			(<any>self).require.config({
				onError: (err: any) => {
					if (err.errorCode === 'load') {
						shell.onUnexpectedError(errors.loaderError(err));
					}
E
Erich Gamma 已提交
156
				}
157
			});
A
Alex Dima 已提交
158
		});
159
	});
E
Erich Gamma 已提交
160
}