/*--------------------------------------------------------------------------------------------- * 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 {TPromise} from 'vs/base/common/winjs.base'; import {IDisposable} from 'vs/base/common/lifecycle'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import * as vscode from 'vscode'; import {IReadOnlyModel, ISingleEditOperation} from 'vs/editor/common/editorCommon'; import * as modes from 'vs/editor/common/modes'; import {WorkspaceSymbolProviderRegistry, IWorkspaceSymbolProvider, IWorkspaceSymbol} from 'vs/workbench/parts/search/common/search'; import {wireCancellationToken} from 'vs/base/common/async'; import {CancellationToken} from 'vs/base/common/cancellation'; import {Position as EditorPosition} from 'vs/editor/common/core/position'; import {Range as EditorRange} from 'vs/editor/common/core/range'; import {ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, ObjectIdentifier} from './extHost.protocol'; import {LanguageConfigurationRegistry, LanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry'; import {trackGarbageCollection} from 'gc-signals'; export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape { private _proxy: ExtHostLanguageFeaturesShape; private _registrations: { [handle: number]: IDisposable; } = Object.create(null); constructor( @IThreadService threadService: IThreadService) { super(); this._proxy = threadService.get(ExtHostContext.ExtHostLanguageFeatures); } $unregister(handle: number): TPromise { let registration = this._registrations[handle]; if (registration) { registration.dispose(); delete this._registrations[handle]; } return undefined; } // --- outline $registerOutlineSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.DocumentSymbolProviderRegistry.register(selector, { provideDocumentSymbols: (model:IReadOnlyModel, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideDocumentSymbols(handle, model.uri)); } }); return undefined; } // --- code lens $registerCodeLensSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.CodeLensProviderRegistry.register(selector, { provideCodeLenses: (model:IReadOnlyModel, token: CancellationToken): modes.ICodeLensSymbol[] | Thenable => { return wireCancellationToken(token, this._proxy.$provideCodeLenses(handle, model.uri)); }, resolveCodeLens: (model:IReadOnlyModel, codeLens: modes.ICodeLensSymbol, token: CancellationToken): modes.ICodeLensSymbol | Thenable => { return wireCancellationToken(token, this._proxy.$resolveCodeLens(handle, model.uri, codeLens)); } }); return undefined; } // --- declaration $registerDeclaractionSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.DefinitionProviderRegistry.register(selector, { provideDefinition: (model, position, token): Thenable => { return wireCancellationToken(token, this._proxy.$provideDefinition(handle, model.uri, position)); } }); return undefined; } // --- extra info $registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.HoverProviderRegistry.register(selector, { provideHover: (model:IReadOnlyModel, position:EditorPosition, token:CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideHover(handle, model.uri, position)); } }); return undefined; } // --- occurrences $registerDocumentHighlightProvider(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.DocumentHighlightProviderRegistry.register(selector, { provideDocumentHighlights: (model: IReadOnlyModel, position: EditorPosition, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideDocumentHighlights(handle, model.uri, position)); } }); return undefined; } // --- references $registerReferenceSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.ReferenceProviderRegistry.register(selector, { provideReferences: (model:IReadOnlyModel, position:EditorPosition, context: modes.ReferenceContext, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideReferences(handle, model.uri, position, context)); } }); return undefined; } // --- quick fix $registerQuickFixSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.CodeActionProviderRegistry.register(selector, { provideCodeActions: (model:IReadOnlyModel, range:EditorRange, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideCodeActions(handle, model.uri, range)); } }); return undefined; } // --- formatting $registerDocumentFormattingSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.DocumentFormattingEditProviderRegistry.register(selector, { provideDocumentFormattingEdits: (model: IReadOnlyModel, options: modes.FormattingOptions, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideDocumentFormattingEdits(handle, model.uri, options)); } }); return undefined; } $registerRangeFormattingSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.DocumentRangeFormattingEditProviderRegistry.register(selector, { provideDocumentRangeFormattingEdits: (model: IReadOnlyModel, range: EditorRange, options: modes.FormattingOptions, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideDocumentRangeFormattingEdits(handle, model.uri, range, options)); } }); return undefined; } $registerOnTypeFormattingSupport(handle: number, selector: vscode.DocumentSelector, autoFormatTriggerCharacters: string[]): TPromise { this._registrations[handle] = modes.OnTypeFormattingEditProviderRegistry.register(selector, { autoFormatTriggerCharacters, provideOnTypeFormattingEdits: (model: IReadOnlyModel, position: EditorPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideOnTypeFormattingEdits(handle, model.uri, position, ch, options)); } }); return undefined; } // --- navigate type $registerNavigateTypeSupport(handle: number): TPromise { this._registrations[handle] = WorkspaceSymbolProviderRegistry.register({ provideWorkspaceSymbols: (search: string): TPromise => { return this._proxy.$provideWorkspaceSymbols(handle, search).then(result => { if (result) { for (const item of result) { trackGarbageCollection(item, ObjectIdentifier.get(item)); } } return result; }); }, resolveWorkspaceSymbol: (item: IWorkspaceSymbol): TPromise => { return this._proxy.$resolveWorkspaceSymbol(handle, item); } }); return undefined; } // --- rename $registerRenameSupport(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.RenameProviderRegistry.register(selector, { provideRenameEdits: (model:IReadOnlyModel, position:EditorPosition, newName: string, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideRenameEdits(handle, model.uri, position, newName)); } }); return undefined; } // --- suggest $registerSuggestSupport(handle: number, selector: vscode.DocumentSelector, triggerCharacters: string[]): TPromise { this._registrations[handle] = modes.SuggestRegistry.register(selector, { triggerCharacters: triggerCharacters, provideCompletionItems: (model:IReadOnlyModel, position:EditorPosition, token:CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideCompletionItems(handle, model.uri, position)).then(result => { if (result && result.suggestions) { for (const suggestion of result.suggestions) { trackGarbageCollection(suggestion, ObjectIdentifier.get(suggestion)); } } return result; }); }, resolveCompletionItem: (model:IReadOnlyModel, position:EditorPosition, suggestion: modes.ISuggestion, token: CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$resolveCompletionItem(handle, model.uri, position, suggestion)); } }); return undefined; } // --- parameter hints $registerSignatureHelpProvider(handle: number, selector: vscode.DocumentSelector, triggerCharacter: string[]): TPromise { this._registrations[handle] = modes.SignatureHelpProviderRegistry.register(selector, { signatureHelpTriggerCharacters: triggerCharacter, provideSignatureHelp: (model:IReadOnlyModel, position:EditorPosition, token:CancellationToken): Thenable => { return wireCancellationToken(token, this._proxy.$provideSignatureHelp(handle, model.uri, position)); } }); return undefined; } // --- links $registerDocumentLinkProvider(handle: number, selector: vscode.DocumentSelector): TPromise { this._registrations[handle] = modes.LinkProviderRegistry.register(selector, { provideLinks: (model, token) => { return wireCancellationToken(token, this._proxy.$provideDocumentLinks(handle, model.uri)); }, resolveLink: (link, token) => { return wireCancellationToken(token, this._proxy.$resolveDocumentLink(handle, link)); } }); return undefined; } // --- configuration $setLanguageConfiguration(handle: number, languageId: string, configuration: vscode.LanguageConfiguration): TPromise { if (configuration.__characterPairSupport) { ( configuration).autoClosingPairs = configuration.__characterPairSupport.autoClosingPairs; } this._registrations[handle] = LanguageConfigurationRegistry.register(languageId, configuration); return undefined; } }