extHost.api.impl.ts 22.1 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

7
import {Emitter} from 'vs/base/common/event';
E
Erich Gamma 已提交
8
import {score} from 'vs/editor/common/modes/languageSelector';
9
import * as Platform from 'vs/base/common/platform';
10
import {regExpLeadsToEndlessLoop} from 'vs/base/common/strings';
E
Erich Gamma 已提交
11 12
import {Remotable, IThreadService} from 'vs/platform/thread/common/thread';
import * as errors from 'vs/base/common/errors';
J
Johannes Rieken 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25
import {ExtHostFileSystemEventService} from 'vs/workbench/api/node/extHostFileSystemEventService';
import {ExtHostModelService, setWordDefinitionFor} from 'vs/workbench/api/node/extHostDocuments';
import {ExtHostConfiguration} from 'vs/workbench/api/node/extHostConfiguration';
import {ExtHostDiagnostics} from 'vs/workbench/api/node/extHostDiagnostics';
import {ExtHostWorkspace} from 'vs/workbench/api/node/extHostWorkspace';
import {ExtHostQuickOpen} from 'vs/workbench/api/node/extHostQuickOpen';
import {ExtHostStatusBar} from 'vs/workbench/api/node/extHostStatusBar';
import {ExtHostCommands} from 'vs/workbench/api/node/extHostCommands';
import {ExtHostOutputService} from 'vs/workbench/api/node/extHostOutputService';
import {ExtHostMessageService} from 'vs/workbench/api/node/extHostMessageService';
import {ExtHostEditors} from 'vs/workbench/api/node/extHostEditors';
import {ExtHostLanguages} from 'vs/workbench/api/node/extHostLanguages';
import {ExtHostLanguageFeatures} from 'vs/workbench/api/node/extHostLanguageFeatures';
26
import * as ExtHostTypeConverters from 'vs/workbench/api/node/extHostTypeConverters';
J
Johannes Rieken 已提交
27 28
import {registerApiCommands} from 'vs/workbench/api/node/extHostApiCommands';
import * as extHostTypes from 'vs/workbench/api/node/extHostTypes';
E
Erich Gamma 已提交
29 30 31 32 33 34
import Modes = require('vs/editor/common/modes');
import {IModeService} from 'vs/editor/common/services/modeService';
import URI from 'vs/base/common/uri';
import Severity from 'vs/base/common/severity';
import {IDisposable} from 'vs/base/common/lifecycle';
import EditorCommon = require('vs/editor/common/editorCommon');
A
Alex Dima 已提交
35
import {IExtensionService, IExtensionDescription} from 'vs/platform/extensions/common/extensions';
36
import {ExtHostExtensionService} from 'vs/platform/extensions/common/nativeExtensionService';
37
import {ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry';
E
Erich Gamma 已提交
38 39 40 41
import {TPromise} from 'vs/base/common/winjs.base';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {CancellationTokenSource} from 'vs/base/common/cancellation';
import vscode = require('vscode');
J
Johannes Rieken 已提交
42
import {TextEditorRevealType} from 'vs/workbench/api/node/mainThreadEditors';
E
Erich Gamma 已提交
43
import * as paths from 'vs/base/common/paths';
J
Johannes Rieken 已提交
44
import {ITelemetryService, ITelemetryInfo} from 'vs/platform/telemetry/common/telemetry';
E
Erich Gamma 已提交
45 46 47 48 49

/**
 * This class implements the API described in vscode.d.ts,
 * for the case of the extensionHost host process
 */
50
export class ExtHostAPIImplementation {
E
Erich Gamma 已提交
51 52 53

	private static _LAST_REGISTER_TOKEN = 0;
	private static generateDisposeToken(): string {
54
		return String(++ExtHostAPIImplementation._LAST_REGISTER_TOKEN);
E
Erich Gamma 已提交
55 56 57 58 59 60
	}

	private _threadService: IThreadService;
	private _proxy: MainProcessVSCodeAPIHelper;

	version: typeof vscode.version;
61
	env: typeof vscode.env;
E
Erich Gamma 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74
	Uri: typeof vscode.Uri;
	Location: typeof vscode.Location;
	Diagnostic: typeof vscode.Diagnostic;
	DiagnosticSeverity: typeof vscode.DiagnosticSeverity;
	Disposable: typeof vscode.Disposable;
	TextEdit: typeof vscode.TextEdit;
	WorkspaceEdit: typeof vscode.WorkspaceEdit;
	ViewColumn: typeof vscode.ViewColumn;
	StatusBarAlignment: typeof vscode.StatusBarAlignment;
	Position: typeof vscode.Position;
	Range: typeof vscode.Range;
	Selection: typeof vscode.Selection;
	CancellationTokenSource: typeof vscode.CancellationTokenSource;
75
	EventEmitter: typeof vscode.EventEmitter;
E
Erich Gamma 已提交
76 77 78 79 80 81 82 83 84 85 86
	Hover: typeof vscode.Hover;
	DocumentHighlightKind: typeof vscode.DocumentHighlightKind;
	DocumentHighlight: typeof vscode.DocumentHighlight;
	SymbolKind: typeof vscode.SymbolKind;
	SymbolInformation: typeof vscode.SymbolInformation;
	CodeLens: typeof vscode.CodeLens;
	ParameterInformation: typeof vscode.ParameterInformation;
	SignatureInformation: typeof vscode.SignatureInformation;
	SignatureHelp: typeof vscode.SignatureHelp;
	CompletionItem: typeof vscode.CompletionItem;
	CompletionItemKind: typeof vscode.CompletionItemKind;
87
	CompletionList: typeof vscode.CompletionList;
E
Erich Gamma 已提交
88 89 90
	IndentAction: typeof vscode.IndentAction;
	OverviewRulerLane: typeof vscode.OverviewRulerLane;
	TextEditorRevealType: typeof vscode.TextEditorRevealType;
91
	EndOfLine: typeof vscode.EndOfLine;
A
Alex Dima 已提交
92
	TextEditorCursorStyle: typeof vscode.TextEditorCursorStyle;
E
Erich Gamma 已提交
93 94 95 96 97 98 99 100
	commands: typeof vscode.commands;
	window: typeof vscode.window;
	workspace: typeof vscode.workspace;
	languages: typeof vscode.languages;
	extensions: typeof vscode.extensions;

	constructor(
		@IThreadService threadService: IThreadService,
A
Alex Dima 已提交
101
		@IExtensionService extensionService: IExtensionService,
102 103
		@IWorkspaceContextService contextService: IWorkspaceContextService,
		@ITelemetryService telemetryService: ITelemetryService
E
Erich Gamma 已提交
104 105 106 107 108 109 110
	) {
		this._threadService = threadService;
		this._proxy = threadService.getRemotable(MainProcessVSCodeAPIHelper);

		this.version = contextService.getConfiguration().env.version;
		this.Uri = URI;
		this.Location = extHostTypes.Location;
111 112
		this.Diagnostic = extHostTypes.Diagnostic;
		this.DiagnosticSeverity = extHostTypes.DiagnosticSeverity;
113
		this.EventEmitter = Emitter;
E
Erich Gamma 已提交
114 115 116 117 118 119 120 121
		this.Disposable = extHostTypes.Disposable;
		this.TextEdit = extHostTypes.TextEdit;
		this.WorkspaceEdit = extHostTypes.WorkspaceEdit;
		this.Position = extHostTypes.Position;
		this.Range = extHostTypes.Range;
		this.Selection = extHostTypes.Selection;
		this.CancellationTokenSource = CancellationTokenSource;
		this.Hover = extHostTypes.Hover;
122 123 124 125
		this.SymbolKind = extHostTypes.SymbolKind;
		this.SymbolInformation = extHostTypes.SymbolInformation;
		this.DocumentHighlightKind = extHostTypes.DocumentHighlightKind;
		this.DocumentHighlight = extHostTypes.DocumentHighlight;
E
Erich Gamma 已提交
126 127 128 129
		this.CodeLens = extHostTypes.CodeLens;
		this.ParameterInformation = extHostTypes.ParameterInformation;
		this.SignatureInformation = extHostTypes.SignatureInformation;
		this.SignatureHelp = extHostTypes.SignatureHelp;
130 131
		this.CompletionItem = extHostTypes.CompletionItem;
		this.CompletionItemKind = extHostTypes.CompletionItemKind;
132
		this.CompletionList = extHostTypes.CompletionList;
133 134 135 136 137 138
		this.ViewColumn = extHostTypes.ViewColumn;
		this.StatusBarAlignment = extHostTypes.StatusBarAlignment;
		this.IndentAction = Modes.IndentAction;
		this.OverviewRulerLane = EditorCommon.OverviewRulerLane;
		this.TextEditorRevealType = TextEditorRevealType;
		this.EndOfLine = extHostTypes.EndOfLine;
A
Alex Dima 已提交
139
		this.TextEditorCursorStyle = EditorCommon.TextEditorCursorStyle;
E
Erich Gamma 已提交
140 141

		errors.setUnexpectedErrorHandler((err) => {
A
Alex Dima 已提交
142
			this._proxy.onUnexpectedExtHostError(errors.transformErrorForSerialization(err));
E
Erich Gamma 已提交
143 144
		});

A
Alex Dima 已提交
145 146
		const extHostCommands = this._threadService.getRemotable(ExtHostCommands);
		const extHostEditors = this._threadService.getRemotable(ExtHostEditors);
J
Johannes Rieken 已提交
147
		const extHostMessageService = new ExtHostMessageService(this._threadService);
A
Alex Dima 已提交
148 149
		const extHostQuickOpen = this._threadService.getRemotable(ExtHostQuickOpen);
		const extHostStatusBar = new ExtHostStatusBar(this._threadService);
150 151
		const extHostOutputService = new ExtHostOutputService(this._threadService);

152 153 154 155
		// the converter might create delegate commands to avoid sending args
		// around all the time
		ExtHostTypeConverters.Command.initialize(extHostCommands);

156
		// env namespace
J
Johannes Rieken 已提交
157 158
		let telemetryInfo: ITelemetryInfo;
		this.env = Object.freeze({
J
Johannes Rieken 已提交
159 160
			get machineId() { return telemetryInfo.machineId; },
			get sessionId() { return telemetryInfo.sessionId; },
161
			get language() { return Platform.language; }
J
Johannes Rieken 已提交
162 163
		});
		telemetryService.getTelemetryInfo().then(info => telemetryInfo = info, errors.onUnexpectedError);
164

165
		// commands namespace
166 167
		this.commands = {
			registerCommand<T>(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
A
Alex Dima 已提交
168
				return extHostCommands.registerCommand(id, command, thisArgs);
169
			},
J
Johannes Rieken 已提交
170 171
			registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => void, thisArg?: any): vscode.Disposable {
				return extHostCommands.registerCommand(id, (...args: any[]) => {
A
Alex Dima 已提交
172
					let activeTextEditor = extHostEditors.getActiveTextEditor();
173 174 175 176 177 178
					if (!activeTextEditor) {
						console.warn('Cannot execute ' + id + ' because there is no active text editor.');
						return;
					}

					activeTextEditor.edit((edit: vscode.TextEditorEdit) => {
J
Johannes Rieken 已提交
179 180 181
						args.unshift(activeTextEditor, edit);
						callback.apply(thisArg, args);

182 183 184 185 186 187 188 189
					}).then((result) => {
						if (!result) {
							console.warn('Edits from command ' + id + ' were not applied.');
						}
					}, (err) => {
						console.warn('An error occured while running command ' + id, err);
					});
				});
190 191
			},
			executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
A
Alex Dima 已提交
192
				return extHostCommands.executeCommand(id, ...args);
193
			},
194
			getCommands(filterInternal: boolean = false): Thenable<string[]> {
A
Alex Dima 已提交
195
				return extHostCommands.getCommands(filterInternal);
196 197 198
			}
		};

E
Erich Gamma 已提交
199 200
		this.window = {
			get activeTextEditor() {
A
Alex Dima 已提交
201
				return extHostEditors.getActiveTextEditor();
E
Erich Gamma 已提交
202 203
			},
			get visibleTextEditors() {
A
Alex Dima 已提交
204
				return extHostEditors.getVisibleTextEditors();
E
Erich Gamma 已提交
205
			},
206
			showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean): TPromise<vscode.TextEditor> {
A
Alex Dima 已提交
207
				return extHostEditors.showTextDocument(document, column, preserveFocus);
E
Erich Gamma 已提交
208 209
			},
			createTextEditorDecorationType(options:vscode.DecorationRenderOptions): vscode.TextEditorDecorationType {
A
Alex Dima 已提交
210
				return extHostEditors.createTextEditorDecorationType(options);
E
Erich Gamma 已提交
211
			},
A
Alex Dima 已提交
212
			onDidChangeActiveTextEditor: extHostEditors.onDidChangeActiveTextEditor.bind(extHostEditors),
E
Erich Gamma 已提交
213
			onDidChangeTextEditorSelection: (listener: (e: vscode.TextEditorSelectionChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
A
Alex Dima 已提交
214
				return extHostEditors.onDidChangeTextEditorSelection(listener, thisArgs, disposables);
E
Erich Gamma 已提交
215 216
			},
			onDidChangeTextEditorOptions: (listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
A
Alex Dima 已提交
217
				return extHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables);
E
Erich Gamma 已提交
218
			},
219
			onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) {
A
Alex Dima 已提交
220
				return extHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables);
221
			},
E
Erich Gamma 已提交
222
			showInformationMessage: (message, ...items) => {
A
Alex Dima 已提交
223
				return extHostMessageService.showMessage(Severity.Info, message, items);
E
Erich Gamma 已提交
224 225
			},
			showWarningMessage: (message, ...items) => {
A
Alex Dima 已提交
226
				return extHostMessageService.showMessage(Severity.Warning, message, items);
E
Erich Gamma 已提交
227 228
			},
			showErrorMessage: (message, ...items) => {
A
Alex Dima 已提交
229
				return extHostMessageService.showMessage(Severity.Error, message, items);
E
Erich Gamma 已提交
230 231
			},
			showQuickPick: (items: any, options: vscode.QuickPickOptions) => {
A
Alex Dima 已提交
232
				return extHostQuickOpen.show(items, options);
E
Erich Gamma 已提交
233
			},
A
Alex Dima 已提交
234
			showInputBox: extHostQuickOpen.input.bind(extHostQuickOpen),
E
Erich Gamma 已提交
235 236

			createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem {
A
Alex Dima 已提交
237
				return extHostStatusBar.createStatusBarEntry(<number>position, priority);
E
Erich Gamma 已提交
238 239
			},
			setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): vscode.Disposable {
A
Alex Dima 已提交
240
				return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable);
E
Erich Gamma 已提交
241
			},
242 243
			createOutputChannel(name: string): vscode.OutputChannel {
				return extHostOutputService.createOutputChannel(name);
E
Erich Gamma 已提交
244 245 246 247
			}
		};

		//
248
		const workspacePath = contextService.getWorkspace() ? contextService.getWorkspace().resource.fsPath : undefined;
A
Alex Dima 已提交
249 250 251
		const extHostFileSystemEvent = threadService.getRemotable(ExtHostFileSystemEventService);
		const extHostWorkspace = new ExtHostWorkspace(this._threadService, workspacePath);
		const extHostDocuments = this._threadService.getRemotable(ExtHostModelService);
E
Erich Gamma 已提交
252 253
		this.workspace = Object.freeze({
			get rootPath() {
A
Alex Dima 已提交
254
				return extHostWorkspace.getPath();
E
Erich Gamma 已提交
255 256 257 258 259
			},
			set rootPath(value) {
				throw errors.readonly();
			},
			asRelativePath: (pathOrUri) => {
A
Alex Dima 已提交
260
				return extHostWorkspace.getRelativePath(pathOrUri);
E
Erich Gamma 已提交
261
			},
262
			findFiles: (include, exclude, maxResults?, token?) => {
A
Alex Dima 已提交
263
				return extHostWorkspace.findFiles(include, exclude, maxResults, token);
E
Erich Gamma 已提交
264 265
			},
			saveAll: (includeUntitled?) => {
A
Alex Dima 已提交
266
				return extHostWorkspace.saveAll(includeUntitled);
E
Erich Gamma 已提交
267 268
			},
			applyEdit(edit: vscode.WorkspaceEdit): TPromise<boolean> {
A
Alex Dima 已提交
269
				return extHostWorkspace.appyEdit(edit);
E
Erich Gamma 已提交
270 271
			},
			createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => {
A
Alex Dima 已提交
272
				return extHostFileSystemEvent.createFileSystemWatcher(pattern, ignoreCreate, ignoreChange, ignoreDelete);
E
Erich Gamma 已提交
273 274
			},
			get textDocuments() {
A
Alex Dima 已提交
275
				return extHostDocuments.getAllDocumentData().map(data => data.document);
E
Erich Gamma 已提交
276 277 278 279
			},
			set textDocuments(value) {
				throw errors.readonly();
			},
280 281 282 283 284 285 286 287 288
			openTextDocument(uriOrFileName: vscode.Uri | string) {
				let uri: URI;
				if (typeof uriOrFileName === 'string') {
					uri = URI.file(uriOrFileName);
				} else if (uriOrFileName instanceof URI) {
					uri = <URI>uriOrFileName;
				} else {
					throw new Error('illegal argument - uriOrFileName');
				}
A
Alex Dima 已提交
289 290
				return extHostDocuments.ensureDocumentData(uri).then(() => {
					const data = extHostDocuments.getDocumentData(uri);
291 292
					return data && data.document;
				});
E
Erich Gamma 已提交
293
			},
J
Johannes Rieken 已提交
294
			registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) {
A
Alex Dima 已提交
295
				return extHostDocuments.registerTextDocumentContentProvider(scheme, provider);
J
Johannes Rieken 已提交
296
			},
E
Erich Gamma 已提交
297
			onDidOpenTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
298
				return extHostDocuments.onDidAddDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
299 300
			},
			onDidCloseTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
301
				return extHostDocuments.onDidRemoveDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
302 303
			},
			onDidChangeTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
304
				return extHostDocuments.onDidChangeDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
305 306
			},
			onDidSaveTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
307
				return extHostDocuments.onDidSaveDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
308 309
			},
			onDidChangeConfiguration: (listener: () => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
A
Alex Dima 已提交
310
				return extHostConfiguration.onDidChangeConfiguration(listener, thisArgs, disposables);
E
Erich Gamma 已提交
311 312
			},
			getConfiguration: (section?: string):vscode.WorkspaceConfiguration => {
A
Alex Dima 已提交
313
				return extHostConfiguration.getConfiguration(section);
E
Erich Gamma 已提交
314 315 316
			}
		});

J
Johannes Rieken 已提交
317 318 319
		//
		registerApiCommands(threadService);

E
Erich Gamma 已提交
320 321
		//
		const languages = new ExtHostLanguages(this._threadService);
322
		const extHostDiagnostics = threadService.getRemotable(ExtHostDiagnostics);
J
Johannes Rieken 已提交
323
		const languageFeatures = threadService.getRemotable(ExtHostLanguageFeatures);
E
Erich Gamma 已提交
324 325 326

		this.languages = {
			createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
A
Alex Dima 已提交
327
				return extHostDiagnostics.createDiagnosticCollection(name);
E
Erich Gamma 已提交
328 329 330 331 332
			},
			getLanguages(): TPromise<string[]> {
				return languages.getLanguages();
			},
			match(selector: vscode.DocumentSelector, document: vscode.TextDocument): number {
333
				return score(selector, <any> document.uri, document.languageId);
E
Erich Gamma 已提交
334 335
			},
			registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable {
J
Johannes Rieken 已提交
336
				return languageFeatures.registerCodeActionProvider(selector, provider);
E
Erich Gamma 已提交
337 338
			},
			registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable {
339
				return languageFeatures.registerCodeLensProvider(selector, provider);
E
Erich Gamma 已提交
340 341
			},
			registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable {
J
Johannes Rieken 已提交
342
				return languageFeatures.registerDefinitionProvider(selector, provider);
E
Erich Gamma 已提交
343 344
			},
			registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
J
Johannes Rieken 已提交
345
				return languageFeatures.registerHoverProvider(selector, provider);
E
Erich Gamma 已提交
346 347
			},
			registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable {
348
				return languageFeatures.registerDocumentHighlightProvider(selector, provider);
E
Erich Gamma 已提交
349 350
			},
			registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable {
J
Johannes Rieken 已提交
351
				return languageFeatures.registerReferenceProvider(selector, provider);
E
Erich Gamma 已提交
352 353
			},
			registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
J
Johannes Rieken 已提交
354
				return languageFeatures.registerRenameProvider(selector, provider);
E
Erich Gamma 已提交
355 356
			},
			registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider): vscode.Disposable {
J
Johannes Rieken 已提交
357
				return languageFeatures.registerDocumentSymbolProvider(selector, provider);
E
Erich Gamma 已提交
358 359
			},
			registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
360
				return languageFeatures.registerWorkspaceSymbolProvider(provider);
E
Erich Gamma 已提交
361 362
			},
			registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable {
363
				return languageFeatures.registerDocumentFormattingEditProvider(selector, provider);
E
Erich Gamma 已提交
364 365
			},
			registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable {
366
				return languageFeatures.registerDocumentRangeFormattingEditProvider(selector, provider);
E
Erich Gamma 已提交
367 368
			},
			registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable {
369
				return languageFeatures.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacters));
E
Erich Gamma 已提交
370 371
			},
			registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, ...triggerCharacters: string[]): vscode.Disposable {
372
				return languageFeatures.registerSignatureHelpProvider(selector, provider, triggerCharacters);
E
Erich Gamma 已提交
373 374
			},
			registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable {
375
				return languageFeatures.registerCompletionItemProvider(selector, provider, triggerCharacters);
E
Erich Gamma 已提交
376 377 378 379 380 381
			},
			setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration):vscode.Disposable => {
				return this._setLanguageConfiguration(language, configuration);
			}
		};

A
Alex Dima 已提交
382
		var extHostConfiguration = threadService.getRemotable(ExtHostConfiguration);
E
Erich Gamma 已提交
383 384 385 386

		//
		this.extensions = {
			getExtension(extensionId: string):Extension<any> {
A
Alex Dima 已提交
387
				let desc = ExtensionsRegistry.getExtensionDescription(extensionId);
E
Erich Gamma 已提交
388
				if (desc) {
A
Alex Dima 已提交
389
					return new Extension(<ExtHostExtensionService> extensionService, desc);
E
Erich Gamma 已提交
390 391 392
				}
			},
			get all():Extension<any>[] {
A
Alex Dima 已提交
393
				return ExtensionsRegistry.getAllExtensionDescriptions().map((desc) => new Extension(<ExtHostExtensionService> extensionService, desc));
E
Erich Gamma 已提交
394
			}
B
Benjamin Pasero 已提交
395
		};
E
Erich Gamma 已提交
396 397 398 399 400 401 402 403 404 405 406

		// Intentionally calling a function for typechecking purposes
		defineAPI(this);
	}

	private _disposableFromToken(disposeToken:string): IDisposable {
		return new extHostTypes.Disposable(() => this._proxy.disposeByToken(disposeToken));
	}

	private _setLanguageConfiguration(modeId: string, configuration: vscode.LanguageConfiguration): vscode.Disposable {

407
		let {wordPattern} = configuration;
E
Erich Gamma 已提交
408

409 410 411 412 413
		// check for a valid word pattern
		if (wordPattern && regExpLeadsToEndlessLoop(wordPattern)) {
			throw new Error(`Invalid language configuration: wordPattern '${wordPattern}' is not allowed to match the empty string.`);
		}

E
Erich Gamma 已提交
414 415 416 417 418 419 420
		// word definition
		if (wordPattern) {
			setWordDefinitionFor(modeId, wordPattern);
		} else {
			setWordDefinitionFor(modeId, null);
		}

421
		return this.Modes_RichEditSupport_register(modeId, configuration);
E
Erich Gamma 已提交
422 423
	}

424
	private Modes_RichEditSupport_register(modeId: string, configuration:vscode.LanguageConfiguration): IDisposable {
425
		let disposeToken = ExtHostAPIImplementation.generateDisposeToken();
426
		this._proxy.Modes_RichEditSupport_register(disposeToken, modeId, configuration);
E
Erich Gamma 已提交
427 428 429 430 431 432
		return this._disposableFromToken(disposeToken);
	}
}

class Extension<T> implements vscode.Extension<T> {

A
Alex Dima 已提交
433
	private _extensionService: ExtHostExtensionService;
E
Erich Gamma 已提交
434 435 436 437 438

	public id: string;
	public extensionPath: string;
	public packageJSON: any;

A
Alex Dima 已提交
439
	constructor(extensionService:ExtHostExtensionService, description:IExtensionDescription) {
A
Alex Dima 已提交
440
		this._extensionService = extensionService;
E
Erich Gamma 已提交
441 442 443 444 445 446
		this.id = description.id;
		this.extensionPath = paths.normalize(description.extensionFolderPath, true);
		this.packageJSON = description;
	}

	get isActive(): boolean {
A
Alex Dima 已提交
447
		return this._extensionService.isActivated(this.id);
E
Erich Gamma 已提交
448 449 450
	}

	get exports(): T {
A
Alex Dima 已提交
451
		return <T>this._extensionService.get(this.id);
E
Erich Gamma 已提交
452 453 454
	}

	activate(): Thenable<T> {
A
Alex Dima 已提交
455
		return this._extensionService.activateById(this.id).then(() => this.exports);
E
Erich Gamma 已提交
456 457 458 459
	}
}

function defineAPI(impl: typeof vscode) {
B
Benjamin Pasero 已提交
460 461
	let node_module = <any>require.__$__nodeRequire('module');
	let original = node_module._load;
E
Erich Gamma 已提交
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
	node_module._load = function load(request, parent, isMain) {
		if (request === 'vscode') {
			return impl;
		}
		return original.apply(this, arguments);
	};
	define('vscode', [], impl);
}

@Remotable.MainContext('MainProcessVSCodeAPIHelper')
export class MainProcessVSCodeAPIHelper {
	protected _modeService: IModeService;
	private _token2Dispose: {
		[token:string]: IDisposable;
	};

	constructor(
		@IModeService modeService: IModeService
	) {
		this._modeService = modeService;
		this._token2Dispose = {};
	}

A
Alex Dima 已提交
485
	public onUnexpectedExtHostError(err: any): void {
E
Erich Gamma 已提交
486 487 488 489 490 491 492 493 494 495
		errors.onUnexpectedError(err);
	}

	public disposeByToken(disposeToken:string): void {
		if (this._token2Dispose[disposeToken]) {
			this._token2Dispose[disposeToken].dispose();
			delete this._token2Dispose[disposeToken];
		}
	}

496 497
	public Modes_RichEditSupport_register(disposeToken:string, modeId: string, configuration:vscode.LanguageConfiguration): void {
		this._token2Dispose[disposeToken] = this._modeService.registerRichEditSupport(modeId, <any>configuration);
E
Erich Gamma 已提交
498 499
	}
}