main.ts 6.5 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 nls = require('vs/nls');
J
Johannes Rieken 已提交
9 10 11
import { TPromise } from 'vs/base/common/winjs.base';
import { WorkbenchShell } from 'vs/workbench/electron-browser/shell';
import { IOptions } from 'vs/workbench/common/options';
12
import * as browser from 'vs/base/browser/browser';
J
Johannes Rieken 已提交
13
import { domContentLoaded } from 'vs/base/browser/dom';
E
Erich Gamma 已提交
14 15 16 17 18 19
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');
J
Johannes Rieken 已提交
20 21
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { EventService } from 'vs/platform/event/common/eventService';
J
Joao Moreno 已提交
22
import { IWorkspace, WorkspaceContextService } from 'vs/platform/workspace/common/workspace';
J
Johannes Rieken 已提交
23
import { WorkspaceConfigurationService } from 'vs/workbench/services/configuration/node/configurationService';
J
Joao Moreno 已提交
24
import { ParsedArgs } from 'vs/platform/environment/common/environment';
J
Johannes Rieken 已提交
25 26
import { realpath } from 'vs/base/node/pfs';
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');
J
Johannes Rieken 已提交
30
import { IPath, IOpenFileRequest } from 'vs/workbench/electron-browser/common';
B
Benjamin Pasero 已提交
31

32 33
import { webFrame } from 'electron';

B
Benjamin Pasero 已提交
34
gracefulFs.gracefulify(fs); // enable gracefulFs
E
Erich Gamma 已提交
35

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

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

43
	userEnv: any; /* vs/code/electron-main/env/IProcessEnvironment*/
44

E
Erich Gamma 已提交
45
	workspacePath?: string;
46 47 48

	zoomLevel?: number;
	fullscreen?: boolean;
E
Erich Gamma 已提交
49 50
}

51
export function startup(configuration: IWindowConfiguration): TPromise<void> {
52
	console.log('vscodeWindowId: ' + configuration.vscodeWindowId);
53 54
	// Ensure others can listen to zoom level changes
	browser.setZoomFactor(webFrame.getZoomFactor());
55
	browser.setZoomLevel(webFrame.getZoomLevel());
56 57
	browser.setFullscreen(!!configuration.fullscreen);

E
Erich Gamma 已提交
58
	// Shell Options
B
polish  
Benjamin Pasero 已提交
59 60 61
	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 已提交
62
	const shellOptions: IOptions = {
63 64
		filesToOpen,
		filesToCreate,
B
Benjamin Pasero 已提交
65
		filesToDiff
E
Erich Gamma 已提交
66 67
	};

68
	if (configuration.performance) {
E
Erich Gamma 已提交
69 70 71
		timer.ENABLE_TIMER = true;
	}

72 73 74 75 76 77
	// Resolve workspace
	return getWorkspace(configuration.workspacePath).then(workspace => {

		// Open workbench
		return openWorkbench(configuration, workspace, shellOptions);
	});
E
Erich Gamma 已提交
78 79
}

80
function toInputs(paths: IPath[], isUntitledFile?: boolean): IResourceInput[] {
E
Erich Gamma 已提交
81
	return paths.map(p => {
82 83 84 85 86 87 88
		const input = <IResourceInput>{};

		if (isUntitledFile) {
			input.resource = uri.from({ scheme: 'untitled', path: p.filePath });
		} else {
			input.resource = uri.file(p.filePath);
		}
E
Erich Gamma 已提交
89 90 91 92 93 94 95 96 97 98 99 100 101 102

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

		return input;
	});
}

103
function getWorkspace(workspacePath: string): TPromise<IWorkspace> {
B
polish  
Benjamin Pasero 已提交
104
	if (!workspacePath) {
105
		return TPromise.as(null);
E
Erich Gamma 已提交
106 107
	}

108 109
	return realpath(workspacePath).then(realWorkspacePath => {

E
Erich Gamma 已提交
110 111 112 113
		// 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
114 115 116
		if (paths.isUNC(realWorkspacePath) && strings.endsWith(realWorkspacePath, paths.nativeSep)) {
			realWorkspacePath = strings.rtrim(realWorkspacePath, paths.nativeSep);
		}
E
Erich Gamma 已提交
117

118 119 120
		const workspaceResource = uri.file(realWorkspacePath);
		const folderName = path.basename(realWorkspacePath) || realWorkspacePath;
		const folderStat = fs.statSync(realWorkspacePath);
E
Erich Gamma 已提交
121

122 123 124 125 126 127 128 129 130 131
		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 已提交
132 133
}

134
function openWorkbench(environment: IWindowConfiguration, workspace: IWorkspace, options: IOptions): TPromise<void> {
B
Benjamin Pasero 已提交
135
	const eventService = new EventService();
136
	const environmentService = new EnvironmentService(environment, environment.execPath, environment.vscodeWindowId);
137
	const contextService = new WorkspaceContextService(workspace);
B
Benjamin Pasero 已提交
138
	const configurationService = new WorkspaceConfigurationService(contextService, eventService, environmentService);
139 140 141 142

	// 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(() => {
143
		timers.perfBeforeDOMContentLoaded = new Date();
144

A
Alex Dima 已提交
145
		return domContentLoaded().then(() => {
146
			timers.perfAfterDOMContentLoaded = new Date();
147 148

			// Open Shell
149
			timers.perfBeforeWorkbenchOpen = new Date();
B
Benjamin Pasero 已提交
150
			const shell = new WorkbenchShell(document.body, workspace, {
151 152
				configurationService,
				eventService,
153 154
				contextService,
				environmentService
155
			}, options);
156 157 158 159 160 161
			shell.open();

			// Inform user about loading issues from the loader
			(<any>self).require.config({
				onError: (err: any) => {
					if (err.errorCode === 'load') {
162
						shell.onUnexpectedError(loaderError(err));
163
					}
E
Erich Gamma 已提交
164
				}
165
			});
A
Alex Dima 已提交
166
		});
167
	});
168 169 170 171 172 173 174 175
}

function loaderError(err: Error): Error {
	if (platform.isWeb) {
		return new Error(nls.localize('loaderError', "Failed to load a required file. Either you are no longer connected to the internet or the server you are connected to is offline. Please refresh the browser to try again."));
	}

	return new Error(nls.localize('loaderErrorNative', "Failed to load a required file. Please restart the application to try again. Details: {0}", JSON.stringify(err)));
E
Erich Gamma 已提交
176
}