extHost.api.impl.ts 22.9 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';
11
import {IThreadService} from 'vs/workbench/services/thread/common/threadService';
E
Erich Gamma 已提交
12
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');
35
import {IExtensionDescription} from 'vs/platform/extensions/common/extensions';
36
import {ExtHostExtensionService} from 'vs/workbench/api/node/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';
45
import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
46
import {MainContext, ExtHostContext, InstanceCollection} from './extHostProtocol';
E
Erich Gamma 已提交
47 48 49 50 51

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

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

	private _proxy: MainProcessVSCodeAPIHelper;

	version: typeof vscode.version;
62
	env: typeof vscode.env;
E
Erich Gamma 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75
	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;
76
	EventEmitter: typeof vscode.EventEmitter;
E
Erich Gamma 已提交
77 78 79 80 81 82 83 84 85 86 87
	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;
88
	CompletionList: typeof vscode.CompletionList;
E
Erich Gamma 已提交
89 90 91
	IndentAction: typeof vscode.IndentAction;
	OverviewRulerLane: typeof vscode.OverviewRulerLane;
	TextEditorRevealType: typeof vscode.TextEditorRevealType;
92
	EndOfLine: typeof vscode.EndOfLine;
A
Alex Dima 已提交
93
	TextEditorCursorStyle: typeof vscode.TextEditorCursorStyle;
E
Erich Gamma 已提交
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(
101 102 103 104
		threadService: IThreadService,
		extensionService: ExtHostExtensionService,
		contextService: IWorkspaceContextService,
		telemetryService: ITelemetryService
E
Erich Gamma 已提交
105
	) {
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
		// Addressable instances
		const col = new InstanceCollection();

		const extHostDocuments = col.define(ExtHostContext.ExtHostModelService).set(new ExtHostModelService(threadService));
		const extHostEditors = col.define(ExtHostContext.ExtHostEditors).set(new ExtHostEditors(threadService, extHostDocuments));
		const extHostCommands = col.define(ExtHostContext.ExtHostCommands).set(new ExtHostCommands(threadService, extHostEditors));
		const extHostConfiguration = col.define(ExtHostContext.ExtHostConfiguration).set(new ExtHostConfiguration());
		const extHostDiagnostics = col.define(ExtHostContext.ExtHostDiagnostics).set(new ExtHostDiagnostics(threadService));
		const languageFeatures = col.define(ExtHostContext.ExtHostLanguageFeatures).set(new ExtHostLanguageFeatures(threadService, extHostDocuments, extHostCommands, extHostDiagnostics));
		const extHostFileSystemEvent = col.define(ExtHostContext.ExtHostFileSystemEventService).set(new ExtHostFileSystemEventService());
		const extHostQuickOpen = col.define(ExtHostContext.ExtHostQuickOpen).set(new ExtHostQuickOpen(threadService));
		col.define(ExtHostContext.ExtHostExtensionService).set(extensionService);

		col.finish(false, threadService);


		// Others
		this._proxy = threadService.get(MainContext.MainProcessVSCodeAPIHelper);
		errors.setUnexpectedErrorHandler((err) => {
			this._proxy.onUnexpectedExtHostError(errors.transformErrorForSerialization(err));
		});

		const extHostMessageService = new ExtHostMessageService(threadService);
		const extHostStatusBar = new ExtHostStatusBar(threadService);
		const extHostOutputService = new ExtHostOutputService(threadService);
		const workspacePath = contextService.getWorkspace() ? contextService.getWorkspace().resource.fsPath : undefined;
		const extHostWorkspace = new ExtHostWorkspace(threadService, workspacePath);
		const languages = new ExtHostLanguages(threadService);

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

E
Erich Gamma 已提交
140 141 142 143

		this.version = contextService.getConfiguration().env.version;
		this.Uri = URI;
		this.Location = extHostTypes.Location;
144 145
		this.Diagnostic = extHostTypes.Diagnostic;
		this.DiagnosticSeverity = extHostTypes.DiagnosticSeverity;
146
		this.EventEmitter = Emitter;
E
Erich Gamma 已提交
147 148 149 150 151 152 153 154
		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;
155 156 157 158
		this.SymbolKind = extHostTypes.SymbolKind;
		this.SymbolInformation = extHostTypes.SymbolInformation;
		this.DocumentHighlightKind = extHostTypes.DocumentHighlightKind;
		this.DocumentHighlight = extHostTypes.DocumentHighlight;
E
Erich Gamma 已提交
159 160 161 162
		this.CodeLens = extHostTypes.CodeLens;
		this.ParameterInformation = extHostTypes.ParameterInformation;
		this.SignatureInformation = extHostTypes.SignatureInformation;
		this.SignatureHelp = extHostTypes.SignatureHelp;
163 164
		this.CompletionItem = extHostTypes.CompletionItem;
		this.CompletionItemKind = extHostTypes.CompletionItemKind;
165
		this.CompletionList = extHostTypes.CompletionList;
166 167 168 169 170 171
		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 已提交
172
		this.TextEditorCursorStyle = EditorCommon.TextEditorCursorStyle;
E
Erich Gamma 已提交
173

174
		// env namespace
J
Johannes Rieken 已提交
175 176
		let telemetryInfo: ITelemetryInfo;
		this.env = Object.freeze({
J
Johannes Rieken 已提交
177 178
			get machineId() { return telemetryInfo.machineId; },
			get sessionId() { return telemetryInfo.sessionId; },
179 180
			get language() { return Platform.language; },
			get appName() { return contextService.getConfiguration().env.appName; }
J
Johannes Rieken 已提交
181 182
		});
		telemetryService.getTelemetryInfo().then(info => telemetryInfo = info, errors.onUnexpectedError);
183

184
		// commands namespace
185 186
		this.commands = {
			registerCommand<T>(id: string, command: <T>(...args: any[]) => T | Thenable<T>, thisArgs?: any): vscode.Disposable {
A
Alex Dima 已提交
187
				return extHostCommands.registerCommand(id, command, thisArgs);
188
			},
J
Johannes Rieken 已提交
189 190
			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 已提交
191
					let activeTextEditor = extHostEditors.getActiveTextEditor();
192 193 194 195 196 197
					if (!activeTextEditor) {
						console.warn('Cannot execute ' + id + ' because there is no active text editor.');
						return;
					}

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

201 202 203 204 205 206 207 208
					}).then((result) => {
						if (!result) {
							console.warn('Edits from command ' + id + ' were not applied.');
						}
					}, (err) => {
						console.warn('An error occured while running command ' + id, err);
					});
				});
209 210
			},
			executeCommand<T>(id: string, ...args: any[]): Thenable<T> {
A
Alex Dima 已提交
211
				return extHostCommands.executeCommand(id, ...args);
212
			},
213
			getCommands(filterInternal: boolean = false): Thenable<string[]> {
A
Alex Dima 已提交
214
				return extHostCommands.getCommands(filterInternal);
215 216 217
			}
		};

E
Erich Gamma 已提交
218 219
		this.window = {
			get activeTextEditor() {
A
Alex Dima 已提交
220
				return extHostEditors.getActiveTextEditor();
E
Erich Gamma 已提交
221 222
			},
			get visibleTextEditors() {
A
Alex Dima 已提交
223
				return extHostEditors.getVisibleTextEditors();
E
Erich Gamma 已提交
224
			},
225
			showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean): TPromise<vscode.TextEditor> {
A
Alex Dima 已提交
226
				return extHostEditors.showTextDocument(document, column, preserveFocus);
E
Erich Gamma 已提交
227 228
			},
			createTextEditorDecorationType(options:vscode.DecorationRenderOptions): vscode.TextEditorDecorationType {
A
Alex Dima 已提交
229
				return extHostEditors.createTextEditorDecorationType(options);
E
Erich Gamma 已提交
230
			},
A
Alex Dima 已提交
231
			onDidChangeActiveTextEditor: extHostEditors.onDidChangeActiveTextEditor.bind(extHostEditors),
E
Erich Gamma 已提交
232
			onDidChangeTextEditorSelection: (listener: (e: vscode.TextEditorSelectionChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
A
Alex Dima 已提交
233
				return extHostEditors.onDidChangeTextEditorSelection(listener, thisArgs, disposables);
E
Erich Gamma 已提交
234 235
			},
			onDidChangeTextEditorOptions: (listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
A
Alex Dima 已提交
236
				return extHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables);
E
Erich Gamma 已提交
237
			},
238
			onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) {
A
Alex Dima 已提交
239
				return extHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables);
240
			},
E
Erich Gamma 已提交
241
			showInformationMessage: (message, ...items) => {
A
Alex Dima 已提交
242
				return extHostMessageService.showMessage(Severity.Info, message, items);
E
Erich Gamma 已提交
243 244
			},
			showWarningMessage: (message, ...items) => {
A
Alex Dima 已提交
245
				return extHostMessageService.showMessage(Severity.Warning, message, items);
E
Erich Gamma 已提交
246 247
			},
			showErrorMessage: (message, ...items) => {
A
Alex Dima 已提交
248
				return extHostMessageService.showMessage(Severity.Error, message, items);
E
Erich Gamma 已提交
249 250
			},
			showQuickPick: (items: any, options: vscode.QuickPickOptions) => {
A
Alex Dima 已提交
251
				return extHostQuickOpen.show(items, options);
E
Erich Gamma 已提交
252
			},
253 254 255
			showInputBox(options?: vscode.InputBoxOptions) {
				return extHostQuickOpen.input(options);
			},
E
Erich Gamma 已提交
256 257

			createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem {
A
Alex Dima 已提交
258
				return extHostStatusBar.createStatusBarEntry(<number>position, priority);
E
Erich Gamma 已提交
259 260
			},
			setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): vscode.Disposable {
A
Alex Dima 已提交
261
				return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable);
E
Erich Gamma 已提交
262
			},
263 264
			createOutputChannel(name: string): vscode.OutputChannel {
				return extHostOutputService.createOutputChannel(name);
E
Erich Gamma 已提交
265 266 267 268 269
			}
		};

		this.workspace = Object.freeze({
			get rootPath() {
A
Alex Dima 已提交
270
				return extHostWorkspace.getPath();
E
Erich Gamma 已提交
271 272 273 274 275
			},
			set rootPath(value) {
				throw errors.readonly();
			},
			asRelativePath: (pathOrUri) => {
A
Alex Dima 已提交
276
				return extHostWorkspace.getRelativePath(pathOrUri);
E
Erich Gamma 已提交
277
			},
278
			findFiles: (include, exclude, maxResults?, token?) => {
A
Alex Dima 已提交
279
				return extHostWorkspace.findFiles(include, exclude, maxResults, token);
E
Erich Gamma 已提交
280 281
			},
			saveAll: (includeUntitled?) => {
A
Alex Dima 已提交
282
				return extHostWorkspace.saveAll(includeUntitled);
E
Erich Gamma 已提交
283 284
			},
			applyEdit(edit: vscode.WorkspaceEdit): TPromise<boolean> {
A
Alex Dima 已提交
285
				return extHostWorkspace.appyEdit(edit);
E
Erich Gamma 已提交
286 287
			},
			createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => {
A
Alex Dima 已提交
288
				return extHostFileSystemEvent.createFileSystemWatcher(pattern, ignoreCreate, ignoreChange, ignoreDelete);
E
Erich Gamma 已提交
289 290
			},
			get textDocuments() {
A
Alex Dima 已提交
291
				return extHostDocuments.getAllDocumentData().map(data => data.document);
E
Erich Gamma 已提交
292 293 294 295
			},
			set textDocuments(value) {
				throw errors.readonly();
			},
296 297 298 299 300 301 302 303 304
			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 已提交
305 306
				return extHostDocuments.ensureDocumentData(uri).then(() => {
					const data = extHostDocuments.getDocumentData(uri);
307 308
					return data && data.document;
				});
E
Erich Gamma 已提交
309
			},
J
Johannes Rieken 已提交
310
			registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) {
A
Alex Dima 已提交
311
				return extHostDocuments.registerTextDocumentContentProvider(scheme, provider);
J
Johannes Rieken 已提交
312
			},
E
Erich Gamma 已提交
313
			onDidOpenTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
314
				return extHostDocuments.onDidAddDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
315 316
			},
			onDidCloseTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
317
				return extHostDocuments.onDidRemoveDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
318 319
			},
			onDidChangeTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
320
				return extHostDocuments.onDidChangeDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
321 322
			},
			onDidSaveTextDocument: (listener, thisArgs?, disposables?) => {
A
Alex Dima 已提交
323
				return extHostDocuments.onDidSaveDocument(listener, thisArgs, disposables);
E
Erich Gamma 已提交
324 325
			},
			onDidChangeConfiguration: (listener: () => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
A
Alex Dima 已提交
326
				return extHostConfiguration.onDidChangeConfiguration(listener, thisArgs, disposables);
E
Erich Gamma 已提交
327 328
			},
			getConfiguration: (section?: string):vscode.WorkspaceConfiguration => {
A
Alex Dima 已提交
329
				return extHostConfiguration.getConfiguration(section);
E
Erich Gamma 已提交
330 331 332 333 334
			}
		});

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

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

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

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

409
		let {wordPattern} = configuration;
E
Erich Gamma 已提交
410

411 412 413 414 415
		// 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 已提交
416 417 418 419 420 421 422
		// word definition
		if (wordPattern) {
			setWordDefinitionFor(modeId, wordPattern);
		} else {
			setWordDefinitionFor(modeId, null);
		}

423 424 425 426 427 428
		// backward compatibility, migrate deprecated setting
		if (configuration.__characterPairSupport && !configuration.autoClosingPairs) {
			configuration.autoClosingPairs = configuration.__characterPairSupport.autoClosingPairs;
			delete configuration.__characterPairSupport;
		}

429
		return this.Modes_RichEditSupport_register(modeId, configuration);
E
Erich Gamma 已提交
430 431
	}

432
	private Modes_RichEditSupport_register(modeId: string, configuration:vscode.LanguageConfiguration): IDisposable {
433
		let disposeToken = ExtHostAPIImplementation.generateDisposeToken();
434
		this._proxy.Modes_RichEditSupport_register(disposeToken, modeId, configuration);
E
Erich Gamma 已提交
435 436 437 438 439 440
		return this._disposableFromToken(disposeToken);
	}
}

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

A
Alex Dima 已提交
441
	private _extensionService: ExtHostExtensionService;
E
Erich Gamma 已提交
442 443 444 445 446

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

A
Alex Dima 已提交
447
	constructor(extensionService:ExtHostExtensionService, description:IExtensionDescription) {
A
Alex Dima 已提交
448
		this._extensionService = extensionService;
E
Erich Gamma 已提交
449 450 451 452 453 454
		this.id = description.id;
		this.extensionPath = paths.normalize(description.extensionFolderPath, true);
		this.packageJSON = description;
	}

	get isActive(): boolean {
A
Alex Dima 已提交
455
		return this._extensionService.isActivated(this.id);
E
Erich Gamma 已提交
456 457 458
	}

	get exports(): T {
A
Alex Dima 已提交
459
		return <T>this._extensionService.get(this.id);
E
Erich Gamma 已提交
460 461 462
	}

	activate(): Thenable<T> {
A
Alex Dima 已提交
463
		return this._extensionService.activateById(this.id).then(() => this.exports);
E
Erich Gamma 已提交
464 465 466
	}
}

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

export class MainProcessVSCodeAPIHelper {
	protected _modeService: IModeService;
	private _token2Dispose: {
		[token:string]: IDisposable;
	};

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

A
Alex Dima 已提交
492
	public onUnexpectedExtHostError(err: any): void {
E
Erich Gamma 已提交
493 494 495 496 497 498 499 500 501 502
		errors.onUnexpectedError(err);
	}

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

503
	public Modes_RichEditSupport_register(disposeToken:string, modeId: string, configuration:vscode.LanguageConfiguration): void {
504
		this._token2Dispose[disposeToken] = LanguageConfigurationRegistry.register(modeId, configuration);
E
Erich Gamma 已提交
505 506
	}
}