/*--------------------------------------------------------------------------------------------- * 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 } from './extHost.protocol'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration'; import { IHeapService } from './mainThreadHeapService'; export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape { private _proxy: ExtHostLanguageFeaturesShape; private _heapService: IHeapService; private _registrations: { [handle: number]: IDisposable; } = Object.create(null); constructor( @IThreadService threadService: IThreadService, @IHeapService heapService: IHeapService ) { super(); this._proxy = threadService.get(ExtHostContext.ExtHostLanguageFeatures); this._heapService = heapService; } $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 this._heapService.trackRecursive(wireCancellationToken(token, this._proxy.$provideCodeLenses(handle, model.uri))); }, resolveCodeLens: (model: IReadOnlyModel, codeLens: modes.ICodeLensSymbol, token: CancellationToken): modes.ICodeLensSymbol | Thenable => { return this._heapService.trackRecursive(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 this._heapService.trackRecursive(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._heapService.trackRecursive(this._proxy.$provideWorkspaceSymbols(handle, search)); }, 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 this._heapService.trackRecursive(wireCancellationToken(token, this._proxy.$provideCompletionItems(handle, model.uri, position))); }, 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 { let configuration: LanguageConfiguration = { comments: _configuration.comments, brackets: _configuration.brackets, wordPattern: _configuration.wordPattern, indentationRules: _configuration.indentationRules, onEnterRules: _configuration.onEnterRules, autoClosingPairs: null, surroundingPairs: null, __electricCharacterSupport: null }; if (_configuration.__characterPairSupport) { // backwards compatibility configuration.autoClosingPairs = _configuration.__characterPairSupport.autoClosingPairs; } if (_configuration.__electricCharacterSupport && _configuration.__electricCharacterSupport.docComment) { configuration.__electricCharacterSupport = { docComment: { open: _configuration.__electricCharacterSupport.docComment.open, close: _configuration.__electricCharacterSupport.docComment.close } }; } this._registrations[handle] = LanguageConfigurationRegistry.register(languageId, configuration); return undefined; } }